INET Framework for OMNeT++/OMNEST
inet::PingApp Class Reference

Generates ping requests and calculates the packet loss and round trip parameters of the replies. More...

#include <PingApp.h>

Inheritance diagram for inet::PingApp:
inet::ApplicationBase inet::INetworkSocket::ICallback inet::OperationalBase inet::OperationalMixin< cSimpleModule > inet::ILifecycle

Public Member Functions

 PingApp ()
 
virtual ~PingApp ()
 
int getPid () const
 
- Public Member Functions inherited from inet::ApplicationBase
 ApplicationBase ()
 
- Public Member Functions inherited from inet::OperationalMixin< cSimpleModule >
virtual ~OperationalMixin ()
 }@ More...
 
- Public Member Functions inherited from inet::ILifecycle
virtual ~ILifecycle ()
 
- Public Member Functions inherited from inet::INetworkSocket::ICallback
virtual ~ICallback ()
 

Protected Member Functions

virtual void initialize (int stage) override
 
virtual int numInitStages () const override
 
virtual void handleMessageWhenUp (cMessage *msg) override
 
virtual void handleSelfMessage (cMessage *msg)
 
virtual void finish () override
 
virtual void refreshDisplay () const override
 
virtual void parseDestAddressesPar ()
 
virtual void startSendingPingRequests ()
 
virtual void scheduleNextPingRequest (simtime_t previous, bool withSleep)
 
virtual void cancelNextPingRequest ()
 
virtual bool isEnabled ()
 
virtual std::vector< L3AddressgetAllAddresses ()
 
virtual void sendPingRequest ()
 
virtual void processPingResponse (int identifier, int seqNumber, Packet *packet)
 
virtual void countPingResponse (int bytes, long seqNo, simtime_t rtt, bool isDup)
 
virtual void handleStartOperation (LifecycleOperation *operation) override
 
virtual void handleStopOperation (LifecycleOperation *operation) override
 
virtual void handleCrashOperation (LifecycleOperation *operation) override
 
virtual void socketDataArrived (INetworkSocket *socket, Packet *packet) override
 
virtual void socketClosed (INetworkSocket *socket) override
 
- Protected Member Functions inherited from inet::ApplicationBase
virtual bool isInitializeStage (int stage) const override
 
virtual bool isModuleStartStage (int stage) const override
 
virtual bool isModuleStopStage (int stage) const override
 
- Protected Member Functions inherited from inet::OperationalMixin< cSimpleModule >
virtual int numInitStages () const override
 
virtual void refreshDisplay () const override
 
virtual void handleMessage (cMessage *msg) override
 
virtual void handleMessageWhenDown (cMessage *msg)
 
virtual bool handleOperationStage (LifecycleOperation *operation, IDoneCallback *doneCallback) override
 Perform one stage of a lifecycle operation. More...
 
virtual State getInitialOperationalState () const
 Returns initial operational state: OPERATING or NOT_OPERATING. More...
 
virtual void handleActiveOperationTimeout (cMessage *message)
 
virtual bool isUp () const
 utility functions More...
 
virtual bool isDown () const
 
virtual void setOperationalState (State newState)
 
virtual void scheduleOperationTimeout (simtime_t timeout)
 
virtual void setupActiveOperation (LifecycleOperation *operation, IDoneCallback *doneCallback, State)
 
virtual void delayActiveOperationFinish (simtime_t timeout)
 
virtual void startActiveOperationExtraTime (simtime_t delay=SIMTIME_ZERO)
 
virtual void startActiveOperationExtraTimeOrFinish (simtime_t extraTime)
 
virtual void finishActiveOperation ()
 

Protected Attributes

L3Address destAddr
 
L3Address srcAddr
 
std::vector< L3AddressdestAddresses
 
int packetSize = 0
 
cPar * sendIntervalPar = nullptr
 
cPar * sleepDurationPar = nullptr
 
int hopLimit = 0
 
int count = 0
 
int destAddrIdx = -1
 
simtime_t startTime
 
simtime_t stopTime
 
CrcMode crcMode = CRC_MODE_UNDEFINED
 
bool printPing = false
 
bool continuous = false
 
SocketMap socketMap
 
INetworkSocketcurrentSocket = nullptr
 
int pid = 0
 
cMessage * timer = nullptr
 
NodeStatusnodeStatus = nullptr
 
simtime_t lastStart
 
long sendSeqNo = 0
 
long expectedReplySeqNo = 0
 
simtime_t sendTimeHistory [PING_HISTORY_SIZE]
 
bool pongReceived [PING_HISTORY_SIZE]
 
cStdDev rttStat
 
long sentCount = 0
 
long lossCount = 0
 
long outOfOrderArrivalCount = 0
 
long numPongs = 0
 
long numDuplicatedPongs = 0
 
- Protected Attributes inherited from inet::OperationalMixin< cSimpleModule >
State operationalState
 
simtime_t lastChange
 
Operation activeOperation
 
cMessage * activeOperationTimeout
 
cMessage * activeOperationExtraTimer
 

Static Protected Attributes

static const std::map< const Protocol *, const Protocol * > l3Echo
 
static simsignal_t rttSignal = registerSignal("rtt")
 
static simsignal_t numLostSignal = registerSignal("numLost")
 
static simsignal_t numOutOfOrderArrivalsSignal = registerSignal("numOutOfOrderArrivals")
 
static simsignal_t pingTxSeqSignal = registerSignal("pingTxSeq")
 
static simsignal_t pingRxSeqSignal = registerSignal("pingRxSeq")
 

Additional Inherited Members

- Protected Types inherited from inet::OperationalMixin< cSimpleModule >
enum  State
 

Detailed Description

Generates ping requests and calculates the packet loss and round trip parameters of the replies.

See NED file for detailed description of operation.

Constructor & Destructor Documentation

◆ PingApp()

inet::PingApp::PingApp ( )
66 {
67 }

◆ ~PingApp()

inet::PingApp::~PingApp ( )
virtual
70 {
71  cancelAndDelete(timer);
73 }

Member Function Documentation

◆ cancelNextPingRequest()

void inet::PingApp::cancelNextPingRequest ( )
protectedvirtual
359 {
360  cancelEvent(timer);
361 }

Referenced by handleCrashOperation(), and handleStopOperation().

◆ countPingResponse()

void inet::PingApp::countPingResponse ( int  bytes,
long  seqNo,
simtime_t  rtt,
bool  isDup 
)
protectedvirtual
485 {
486  EV_INFO << "Ping reply #" << seqNo << " arrived, rtt=" << (rtt == SIMTIME_ZERO ? "unknown" : rtt.str().c_str()) << (isDup ? ", duplicated" : "") << "\n";
487  emit(pingRxSeqSignal, seqNo);
488 
489  if (isDup)
491  else
492  numPongs++;
493 
494  // count only non 0 RTT values as 0s are invalid
495  if (rtt > SIMTIME_ZERO && !isDup) {
496  rttStat.collect(rtt);
497  emit(rttSignal, rtt);
498  }
499 
500  if (seqNo == expectedReplySeqNo) {
501  // expected ping reply arrived; expect next sequence number
503  }
504  else if (seqNo > expectedReplySeqNo) {
505  EV_DETAIL << "Jump in seq numbers, assuming pings since #" << expectedReplySeqNo << " got lost\n";
506 
507  // jump in the sequence: count pings in gap as lost for now
508  // (if they arrive later, we'll decrement back the loss counter)
509  long jump = seqNo - expectedReplySeqNo;
510  lossCount += jump;
511  emit(numLostSignal, lossCount);
512 
513  // expect sequence numbers to continue from here
514  expectedReplySeqNo = seqNo + 1;
515  }
516  else { // seqNo < expectedReplySeqNo
517  // ping reply arrived too late: count as out-of-order arrival (not loss after all)
518  EV_DETAIL << "Arrived out of order (too late)\n";
520  if (!isDup && rtt > SIMTIME_ZERO)
521  lossCount--;
523  emit(numLostSignal, lossCount);
524  }
525 }

Referenced by processPingResponse().

◆ finish()

void inet::PingApp::finish ( )
overrideprotectedvirtual
565 {
566  if (sendSeqNo == 0) {
567  if (printPing)
568  EV_DETAIL << getFullPath() << ": No pings sent, skipping recording statistics and printing results.\n";
569  return;
570  }
571 
573  // record statistics
574  recordScalar("Pings sent", sendSeqNo);
575  recordScalar("ping loss rate (%)", 100 * lossCount / (double)sendSeqNo);
576  recordScalar("ping out-of-order rate (%)", 100 * outOfOrderArrivalCount / (double)sendSeqNo);
577 
578  // print it to stdout as well
579  if (printPing) {
580  cout << "--------------------------------------------------------" << endl;
581  cout << "\t" << getFullPath() << endl;
582  cout << "--------------------------------------------------------" << endl;
583 
584  cout << "sent: " << sendSeqNo << " received: " << numPongs << " loss rate (%): " << (100 * lossCount / (double)sendSeqNo) << endl;
585  cout << "round-trip min/avg/max (ms): " << (rttStat.getMin() * 1000.0) << "/"
586  << (rttStat.getMean() * 1000.0) << "/" << (rttStat.getMax() * 1000.0) << endl;
587  cout << "stddev (ms): " << (rttStat.getStddev() * 1000.0) << " variance:" << rttStat.getVariance() << endl;
588  cout << "--------------------------------------------------------" << endl;
589  }
590 }

◆ getAllAddresses()

std::vector< L3Address > inet::PingApp::getAllAddresses ( )
protectedvirtual
528 {
529  std::vector<L3Address> result;
530 
531  int lastId = getSimulation()->getLastComponentId();
532 
533  for (int i = 0; i <= lastId; i++) {
534  IInterfaceTable *ift = dynamic_cast<IInterfaceTable *>(getSimulation()->getModule(i));
535  if (ift) {
536  for (int j = 0; j < ift->getNumInterfaces(); j++) {
537  NetworkInterface *ie = ift->getInterface(j);
538  if (ie && !ie->isLoopback()) {
539 #ifdef INET_WITH_IPv4
540  auto ipv4Data = ie->findProtocolData<Ipv4InterfaceData>();
541  if (ipv4Data != nullptr) {
542  Ipv4Address address = ipv4Data->getIPAddress();
543  if (!address.isUnspecified())
544  result.push_back(L3Address(address));
545  }
546 #endif // ifdef INET_WITH_IPv4
547 #ifdef INET_WITH_IPv6
548  auto ipv6Data = ie->findProtocolData<Ipv6InterfaceData>();
549  if (ipv6Data != nullptr) {
550  for (int k = 0; k < ipv6Data->getNumAddresses(); k++) {
551  Ipv6Address address = ipv6Data->getAddress(k);
552  if (!address.isUnspecified() && address.isGlobal())
553  result.push_back(L3Address(address));
554  }
555  }
556 #endif // ifdef INET_WITH_IPv6
557  }
558  }
559  }
560  }
561  return result;
562 }

Referenced by parseDestAddressesPar().

◆ getPid()

int inet::PingApp::getPid ( ) const
inline
108 { return pid; }

◆ handleCrashOperation()

void inet::PingApp::handleCrashOperation ( LifecycleOperation operation)
overrideprotectedvirtual

Implements inet::OperationalMixin< cSimpleModule >.

326 {
327  pid = -1;
328  lastStart = -1;
330  srcAddr = destAddr = L3Address();
331  destAddresses.clear();
332  destAddrIdx = -1;
334  currentSocket = nullptr;
335  // TODO remove check?
336  if (operation->getRootModule() != getContainingNode(this)) {
337  // TODO destroy sockets
338  for (auto socket : socketMap.getMap())
339  socket.second->destroy();
341  }
342 }

◆ handleMessageWhenUp()

void inet::PingApp::handleMessageWhenUp ( cMessage *  msg)
overrideprotectedvirtual

Implements inet::OperationalMixin< cSimpleModule >.

211 {
212  if (msg->isSelfMessage())
213  handleSelfMessage(msg);
214  else {
215  auto socket = check_and_cast_nullable<INetworkSocket *>(socketMap.findSocketFor(msg));
216  if (socket)
217  socket->processMessage(msg);
218  else
219  throw cRuntimeError("Unaccepted message: %s(%s)", msg->getName(), msg->getClassName());
220  }
221  if (operationalState == State::STOPPING_OPERATION && socketMap.size() == 0)
222  startActiveOperationExtraTimeOrFinish(par("stopOperationExtraTime"));
223 }

◆ handleSelfMessage()

void inet::PingApp::handleSelfMessage ( cMessage *  msg)
protectedvirtual
142 {
143  if (msg->getKind() == PING_FIRST_ADDR) {
144  srcAddr = L3AddressResolver().resolve(par("srcAddr"));
146  if (destAddresses.empty()) {
147  return;
148  }
149  destAddrIdx = 0;
150  msg->setKind(PING_CHANGE_ADDR);
151  }
152 
153  if (msg->getKind() == PING_CHANGE_ADDR) {
154  if (destAddrIdx >= (int)destAddresses.size())
155  return;
157  EV_INFO << "Starting up: dest=" << destAddr << " src=" << srcAddr << "seqNo=" << sendSeqNo << endl;
158  ASSERT(!destAddr.isUnspecified());
159  const Protocol *networkProtocol = nullptr;
160  const char *networkProtocolAsString = par("networkProtocol");
161  if (*networkProtocolAsString)
162  networkProtocol = Protocol::getProtocol(networkProtocolAsString);
163  else {
164  switch (destAddr.getType()) {
165  case L3Address::IPv4: networkProtocol = &Protocol::ipv4; break;
166  case L3Address::IPv6: networkProtocol = &Protocol::ipv6; break;
167  case L3Address::MODULEID:
168  case L3Address::MODULEPATH: networkProtocol = &Protocol::nextHopForwarding; break;
169  default: throw cRuntimeError("unknown address type: %d(%s)", (int)destAddr.getType(), L3Address::getTypeName(destAddr.getType()));
170  }
171  }
172  const Protocol *icmp = l3Echo.at(networkProtocol);
173 
174  for (auto socket : socketMap.getMap()) {
175  socket.second->close();
176  }
177  currentSocket = nullptr;
178  if (networkProtocol == &Protocol::ipv4)
179  currentSocket = new Ipv4Socket(gate("socketOut"));
180  else if (networkProtocol == &Protocol::ipv6)
181  currentSocket = new Ipv6Socket(gate("socketOut"));
182  else
183  currentSocket = new L3Socket(networkProtocol, gate("socketOut"));
185  currentSocket->bind(icmp, L3Address());
186  currentSocket->setCallback(this);
187  msg->setKind(PING_SEND);
188  }
189 
190  ASSERT2(msg->getKind() == PING_SEND, "Unknown kind in self message.");
191 
192  // send a ping
193  sendPingRequest();
194 
195  if (count > 0 && sendSeqNo % count == 0) {
196  // choose next dest address
197  destAddrIdx++;
198  msg->setKind(PING_CHANGE_ADDR);
199  if (destAddrIdx >= (int)destAddresses.size()) {
200  if (continuous) {
202  }
203  }
204  }
205 
206  // then schedule next one if needed
207  scheduleNextPingRequest(simTime(), msg->getKind() == PING_CHANGE_ADDR);
208 }

Referenced by handleMessageWhenUp().

◆ handleStartOperation()

void inet::PingApp::handleStartOperation ( LifecycleOperation operation)
overrideprotectedvirtual

Implements inet::OperationalMixin< cSimpleModule >.

290 {
291  if (isEnabled())
293 }

◆ handleStopOperation()

void inet::PingApp::handleStopOperation ( LifecycleOperation operation)
overrideprotectedvirtual

Implements inet::OperationalMixin< cSimpleModule >.

307 {
308  pid = -1;
309  lastStart = -1;
311  srcAddr = destAddr = L3Address();
312  destAddresses.clear();
313  destAddrIdx = -1;
315  currentSocket = nullptr;
316  // TODO close sockets
317  // TODO remove getMap()
318  if (socketMap.size() > 0) {
319  for (auto socket : socketMap.getMap())
320  socket.second->close();
321  }
322  delayActiveOperationFinish(par("stopOperationTimeout"));
323 }

◆ initialize()

void inet::PingApp::initialize ( int  stage)
overrideprotectedvirtual

Reimplemented from inet::OperationalMixin< cSimpleModule >.

76 {
78 
79  if (stage == INITSTAGE_LOCAL) {
80  // read params
81  // (defer reading srcAddr/destAddr to when ping starts, maybe
82  // addresses will be assigned later by some protocol)
83  packetSize = par("packetSize");
84  sendIntervalPar = &par("sendInterval");
85  sleepDurationPar = &par("sleepDuration");
86  hopLimit = par("hopLimit");
87  count = par("count");
88 // if (count <= 0 && count != -1)
89 // throw cRuntimeError("Invalid count=%d parameter (should use -1 or a larger than zero value)", count);
90  startTime = par("startTime");
91  stopTime = par("stopTime");
92  if (stopTime >= SIMTIME_ZERO && stopTime < startTime)
93  throw cRuntimeError("Invalid startTime/stopTime parameters");
94  printPing = par("printPing");
95  continuous = par("continuous");
96 
97  const char *crcModeString = par("crcMode");
98  crcMode = parseCrcMode(crcModeString, false);
99 
100  // state
101  pid = -1;
102  lastStart = -1;
104  for (int i = 0; i < PING_HISTORY_SIZE; i++) {
105  sendTimeHistory[i] = SIMTIME_MAX;
106  pongReceived[i] = false;
107  }
108  WATCH(sendSeqNo);
109  WATCH(expectedReplySeqNo);
110 
111  // statistics
112  rttStat.setName("pingRTT");
114  WATCH(lossCount);
115  WATCH(outOfOrderArrivalCount);
116  WATCH(numPongs);
117 
118  // references
119  timer = new cMessage("sendPing", PING_FIRST_ADDR);
120  }
121 }

◆ isEnabled()

bool inet::PingApp::isEnabled ( )
protectedvirtual
364 {
365  return par("destAddr").stringValue()[0] && (count == -1 || sentCount < count);
366 }

Referenced by handleStartOperation().

◆ numInitStages()

virtual int inet::PingApp::numInitStages ( ) const
inlineoverrideprotectedvirtual
80 { return NUM_INIT_STAGES; }

◆ parseDestAddressesPar()

void inet::PingApp::parseDestAddressesPar ( )
protectedvirtual
124 {
125  srcAddr = L3AddressResolver().resolve(par("srcAddr"));
126  const char *destAddrs = par("destAddr");
127  if (!strcmp(destAddrs, "*")) {
129  }
130  else {
131  cStringTokenizer tokenizer(destAddrs);
132  const char *token;
133 
134  while ((token = tokenizer.nextToken()) != nullptr) {
135  L3Address addr = L3AddressResolver().resolve(token);
136  destAddresses.push_back(addr);
137  }
138  }
139 }

Referenced by handleSelfMessage().

◆ processPingResponse()

void inet::PingApp::processPingResponse ( int  identifier,
int  seqNumber,
Packet packet 
)
protectedvirtual
446 {
447  const auto& pingPayload = packet->peekDataAt(B(0), packet->getDataLength());
448  if (originatorId != pid) {
449  EV_WARN << "Received response was not sent by this application, dropping packet\n";
450  return;
451  }
452 
453  // get src, hopCount etc from packet, and print them
454  L3Address src = packet->getTag<L3AddressInd>()->getSrcAddress();
455 // L3Address dest = msg->getTag<L3AddressInd>()->getDestination();
456  auto& msgHopCountTag = packet->findTag<HopLimitInd>();
457  int msgHopCount = msgHopCountTag ? msgHopCountTag->getHopLimit() : -1;
458 
459  // calculate the RTT time by looking up the the send time of the packet
460  // if the send time is no longer available (i.e. the packet is very old and the
461  // sendTime was overwritten in the circular buffer) then we just return a 0
462  // to signal that this value should not be used during the RTT statistics)
463  simtime_t rtt = SIMTIME_ZERO;
464  bool isDup = false;
465  if (sendSeqNo - seqNo < PING_HISTORY_SIZE) {
466  int idx = seqNo % PING_HISTORY_SIZE;
467  rtt = simTime() - sendTimeHistory[idx];
468  isDup = pongReceived[idx];
469  pongReceived[idx] = true;
470  }
471 
472  if (printPing) {
473  cout << getFullPath() << ": reply of " << packet->getByteLength()
474  << " bytes from " << src
475  << " icmp_seq=" << seqNo << " ttl=" << msgHopCount
476  << " time=" << (rtt * 1000) << " msec"
477  << " (" << packet->getName() << ")" << endl;
478  }
479 
480  // update statistics
481  countPingResponse(B(pingPayload->getChunkLength()).get(), seqNo, rtt, isDup);
482 }

Referenced by socketDataArrived().

◆ refreshDisplay()

void inet::PingApp::refreshDisplay ( ) const
overrideprotectedvirtual
281 {
283 
284  char buf[40];
285  sprintf(buf, "sent: %ld pks\nrcvd: %ld pks", sentCount, numPongs);
286  getDisplayString().setTagArg("t", 0, buf);
287 }

◆ scheduleNextPingRequest()

void inet::PingApp::scheduleNextPingRequest ( simtime_t  previous,
bool  withSleep 
)
protectedvirtual
345 {
346  simtime_t next;
347  if (previous < SIMTIME_ZERO)
348  next = simTime() <= startTime ? startTime : simTime();
349  else {
350  next = previous + *sendIntervalPar;
351  if (withSleep)
352  next += *sleepDurationPar;
353  }
354  if (stopTime < SIMTIME_ZERO || next < stopTime)
355  scheduleAt(next, timer);
356 }

Referenced by handleSelfMessage(), and startSendingPingRequests().

◆ sendPingRequest()

void inet::PingApp::sendPingRequest ( )
protectedvirtual
369 {
370  char name[32];
371  sprintf(name, "ping%ld", sendSeqNo);
372 
373  ASSERT(pid != -1);
374 
375  Packet *outPacket = new Packet(name);
376  auto payload = makeShared<ByteCountChunk>(B(packetSize));
377 
378  switch (destAddr.getType()) {
379  case L3Address::IPv4: {
380 #ifdef INET_WITH_IPv4
381  const auto& request = makeShared<IcmpEchoRequest>();
382  request->setIdentifier(pid);
383  request->setSeqNumber(sendSeqNo);
384  outPacket->insertAtBack(payload);
385  Icmp::insertCrc(crcMode, request, outPacket);
386  outPacket->insertAtFront(request);
387  outPacket->addTag<PacketProtocolTag>()->setProtocol(&Protocol::icmpv4);
388  break;
389 #else
390  throw cRuntimeError("INET compiled without Ipv4");
391 #endif
392  }
393  case L3Address::IPv6: {
394 #ifdef INET_WITH_IPv6
395  const auto& request = makeShared<Icmpv6EchoRequestMsg>();
396  request->setIdentifier(pid);
397  request->setSeqNumber(sendSeqNo);
398  outPacket->insertAtBack(payload);
399  Icmpv6::insertCrc(crcMode, request, outPacket);
400  outPacket->insertAtFront(request);
401  outPacket->addTag<PacketProtocolTag>()->setProtocol(&Protocol::icmpv6);
402  break;
403 #else
404  throw cRuntimeError("INET compiled without Ipv6");
405 #endif
406  }
407  case L3Address::MODULEID:
408  case L3Address::MODULEPATH: {
409 #ifdef INET_WITH_NEXTHOP
410  const auto& request = makeShared<EchoPacket>();
411  request->setChunkLength(B(8));
412  request->setType(ECHO_PROTOCOL_REQUEST);
413  request->setIdentifier(pid);
414  request->setSeqNumber(sendSeqNo);
415  outPacket->insertAtBack(payload);
416 // insertCrc(crcMode, request, outPacket);
417  outPacket->insertAtFront(request);
418  outPacket->addTag<PacketProtocolTag>()->setProtocol(&Protocol::echo);
419  break;
420 #else
421  throw cRuntimeError("INET compiled without Next Hop Forwarding");
422 #endif
423  }
424  default:
425  throw cRuntimeError("Unaccepted destination address type: %d (address: %s)", (int)destAddr.getType(), destAddr.str().c_str());
426  }
427 
428  auto addressReq = outPacket->addTag<L3AddressReq>();
429  addressReq->setSrcAddress(srcAddr);
430  addressReq->setDestAddress(destAddr);
431  if (hopLimit != -1)
432  outPacket->addTag<HopLimitReq>()->setHopLimit(hopLimit);
433  EV_INFO << "Sending ping request #" << sendSeqNo << " to lower layer.\n";
434  currentSocket->send(outPacket);
435 
436  // store the sending time in a circular buffer so we can compute RTT when the packet returns
439  emit(pingTxSeqSignal, sendSeqNo);
440 
441  sendSeqNo++;
442  sentCount++;
443 }

Referenced by handleSelfMessage().

◆ socketClosed()

void inet::PingApp::socketClosed ( INetworkSocket socket)
overrideprotectedvirtual

Implements inet::INetworkSocket::ICallback.

274 {
275  if (socket == currentSocket)
276  currentSocket = nullptr;
277  delete socketMap.removeSocket(socket);
278 }

◆ socketDataArrived()

void inet::PingApp::socketDataArrived ( INetworkSocket socket,
Packet packet 
)
overrideprotectedvirtual

Implements inet::INetworkSocket::ICallback.

226 {
227 #ifdef INET_WITH_IPv4
228  if (packet->getTag<PacketProtocolTag>()->getProtocol() == &Protocol::icmpv4) {
229  const auto& icmpHeader = packet->popAtFront<IcmpHeader>();
230  if (icmpHeader->getType() == ICMP_ECHO_REPLY) {
231  const auto& echoReply = CHK(dynamicPtrCast<const IcmpEchoReply>(icmpHeader));
232  processPingResponse(echoReply->getIdentifier(), echoReply->getSeqNumber(), packet);
233  }
234  else {
235  // process other icmp messages, process icmp errors
236  }
237  delete packet;
238  }
239  else
240 #endif
241 #ifdef INET_WITH_IPv6
242  if (packet->getTag<PacketProtocolTag>()->getProtocol() == &Protocol::icmpv6) {
243  const auto& icmpHeader = packet->popAtFront<Icmpv6Header>();
244  if (icmpHeader->getType() == ICMPv6_ECHO_REPLY) {
245  const auto& echoReply = CHK(dynamicPtrCast<const Icmpv6EchoReplyMsg>(icmpHeader));
246  processPingResponse(echoReply->getIdentifier(), echoReply->getSeqNumber(), packet);
247  }
248  else {
249  // process other icmpv6 messages, process icmpv6 errors
250  }
251  delete packet;
252  }
253  else
254 #endif
255 #ifdef INET_WITH_NEXTHOP
256  if (packet->getTag<PacketProtocolTag>()->getProtocol() == &Protocol::echo) {
257  const auto& icmpHeader = packet->popAtFront<EchoPacket>();
258  if (icmpHeader->getType() == ECHO_PROTOCOL_REPLY) {
259  processPingResponse(icmpHeader->getIdentifier(), icmpHeader->getSeqNumber(), packet);
260  }
261  else {
262  // process other icmp messages, process icmp errors
263  }
264  delete packet;
265  }
266  else
267 #endif
268  {
269  throw cRuntimeError("Unaccepted packet: %s(%s)", packet->getName(), packet->getClassName());
270  }
271 }

◆ startSendingPingRequests()

void inet::PingApp::startSendingPingRequests ( )
protectedvirtual
296 {
297  ASSERT(!timer->isScheduled());
298  pid = getSimulation()->getUniqueNumber();
299  lastStart = simTime();
300  timer->setKind(PING_FIRST_ADDR);
301  sentCount = 0;
302  sendSeqNo = 0;
303  scheduleNextPingRequest(-1, false);
304 }

Referenced by handleStartOperation().

Member Data Documentation

◆ continuous

bool inet::PingApp::continuous = false
protected

Referenced by handleSelfMessage(), and initialize().

◆ count

int inet::PingApp::count = 0
protected

◆ crcMode

CrcMode inet::PingApp::crcMode = CRC_MODE_UNDEFINED
protected

Referenced by initialize(), and sendPingRequest().

◆ currentSocket

INetworkSocket* inet::PingApp::currentSocket = nullptr
protected

◆ destAddr

L3Address inet::PingApp::destAddr
protected

◆ destAddresses

std::vector<L3Address> inet::PingApp::destAddresses
protected

◆ destAddrIdx

int inet::PingApp::destAddrIdx = -1
protected

◆ expectedReplySeqNo

long inet::PingApp::expectedReplySeqNo = 0
protected

◆ hopLimit

int inet::PingApp::hopLimit = 0
protected

Referenced by initialize(), and sendPingRequest().

◆ l3Echo

const std::map< const Protocol *, const Protocol * > inet::PingApp::l3Echo
staticprotected

Referenced by handleSelfMessage().

◆ lastStart

simtime_t inet::PingApp::lastStart
protected

◆ lossCount

long inet::PingApp::lossCount = 0
protected

◆ nodeStatus

NodeStatus* inet::PingApp::nodeStatus = nullptr
protected

◆ numDuplicatedPongs

long inet::PingApp::numDuplicatedPongs = 0
protected

Referenced by countPingResponse().

◆ numLostSignal

simsignal_t inet::PingApp::numLostSignal = registerSignal("numLost")
staticprotected

Referenced by countPingResponse().

◆ numOutOfOrderArrivalsSignal

simsignal_t inet::PingApp::numOutOfOrderArrivalsSignal = registerSignal("numOutOfOrderArrivals")
staticprotected

Referenced by countPingResponse().

◆ numPongs

long inet::PingApp::numPongs = 0
protected

◆ outOfOrderArrivalCount

long inet::PingApp::outOfOrderArrivalCount = 0
protected

◆ packetSize

int inet::PingApp::packetSize = 0
protected

Referenced by initialize(), and sendPingRequest().

◆ pid

◆ pingRxSeqSignal

simsignal_t inet::PingApp::pingRxSeqSignal = registerSignal("pingRxSeq")
staticprotected

Referenced by countPingResponse().

◆ pingTxSeqSignal

simsignal_t inet::PingApp::pingTxSeqSignal = registerSignal("pingTxSeq")
staticprotected

Referenced by sendPingRequest().

◆ pongReceived

bool inet::PingApp::pongReceived[PING_HISTORY_SIZE]
protected

◆ printPing

bool inet::PingApp::printPing = false
protected

◆ rttSignal

simsignal_t inet::PingApp::rttSignal = registerSignal("rtt")
staticprotected

Referenced by countPingResponse().

◆ rttStat

cStdDev inet::PingApp::rttStat
protected

◆ sendIntervalPar

cPar* inet::PingApp::sendIntervalPar = nullptr
protected

◆ sendSeqNo

◆ sendTimeHistory

simtime_t inet::PingApp::sendTimeHistory[PING_HISTORY_SIZE]
protected

◆ sentCount

long inet::PingApp::sentCount = 0
protected

◆ sleepDurationPar

cPar* inet::PingApp::sleepDurationPar = nullptr
protected

◆ socketMap

◆ srcAddr

◆ startTime

simtime_t inet::PingApp::startTime
protected

◆ stopTime

simtime_t inet::PingApp::stopTime
protected

◆ timer

cMessage* inet::PingApp::timer = nullptr
protected

The documentation for this class was generated from the following files:
CHK
#define CHK(x)
Definition: INETDefs.h:87
inet::L3Address::MODULEID
@ MODULEID
Definition: L3Address.h:40
inet::ECHO_PROTOCOL_REQUEST
@ ECHO_PROTOCOL_REQUEST
Definition: EchoPacket_m.h:58
inet::Icmpv6::insertCrc
static void insertCrc(CrcMode crcMode, const Ptr< Icmpv6Header > &icmpHeader, Packet *packet)
Definition: Icmpv6.cc:333
inet::PingApp::rttStat
cStdDev rttStat
Definition: PingApp.h:66
inet::OperationalMixin< cSimpleModule >::operationalState
State operationalState
Definition: OperationalMixin.h:23
inet::PING_CHANGE_ADDR
@ PING_CHANGE_ADDR
Definition: PingApp_m.h:54
inet::PingApp::numDuplicatedPongs
long numDuplicatedPongs
Definition: PingApp.h:76
inet::PingApp::lastStart
simtime_t lastStart
Definition: PingApp.h:57
inet::Protocol::ipv4
static const Protocol ipv4
Definition: Protocol.h:93
inet::PingApp::parseDestAddressesPar
virtual void parseDestAddressesPar()
Definition: PingApp.cc:123
inet::Protocol::getProtocol
static const Protocol * getProtocol(int id)
Definition: Protocol.cc:50
inet::Protocol::ipv6
static const Protocol ipv6
Definition: Protocol.h:94
inet::INetworkSocket::close
virtual void close()=0
Closes this socket releasing all resources.
inet::getContainingNode
cModule * getContainingNode(const cModule *from)
Find the node containing the given module.
Definition: ModuleAccess.cc:40
inet::OperationalMixin< cSimpleModule >::initialize
virtual void initialize(int stage) override
Definition: OperationalMixinImpl.h:26
inet::Protocol::icmpv4
static const Protocol icmpv4
Definition: Protocol.h:71
inet::PingApp::startSendingPingRequests
virtual void startSendingPingRequests()
Definition: PingApp.cc:295
inet::PingApp::expectedReplySeqNo
long expectedReplySeqNo
Definition: PingApp.h:59
inet::L3Address::str
std::string str() const
Definition: L3Address.cc:88
inet::PingApp::destAddr
L3Address destAddr
Definition: PingApp.h:36
inet::Icmp::insertCrc
static void insertCrc(CrcMode crcMode, const Ptr< IcmpHeader > &icmpHeader, Packet *payload)
Definition: Icmp.cc:351
L3AddressInd
removed DscpReq Ipv4ControlInfo Ipv6ControlInfo up L3AddressInd L3AddressInd
Definition: IUdp-gates.txt:20
inet::PingApp::sleepDurationPar
cPar * sleepDurationPar
Definition: PingApp.h:41
inet::parseCrcMode
CrcMode parseCrcMode(const char *crcModeString, bool allowDisable)
Definition: CrcMode.cc:14
inet::SocketMap::deleteSockets
void deleteSockets()
Deletes the socket objects.
Definition: SocketMap.cc:44
inet::PingApp::lossCount
long lossCount
Definition: PingApp.h:73
inet::PING_SEND
@ PING_SEND
Definition: PingApp_m.h:55
inet::PingApp::hopLimit
int hopLimit
Definition: PingApp.h:42
inet::ISocket::send
virtual void send(Packet *packet)=0
inet::Protocol::nextHopForwarding
static const Protocol nextHopForwarding
Definition: Protocol.h:128
inet::L3Address::IPv4
@ IPv4
Definition: L3Address.h:35
inet::L3Address::MODULEPATH
@ MODULEPATH
Definition: L3Address.h:39
inet::PingApp::numOutOfOrderArrivalsSignal
static simsignal_t numOutOfOrderArrivalsSignal
Definition: PingApp.h:69
inet::PingApp::pongReceived
bool pongReceived[PING_HISTORY_SIZE]
Definition: PingApp.h:61
inet::L3Address::isUnspecified
bool isUnspecified() const
Definition: L3Address.cc:138
inet::PingApp::countPingResponse
virtual void countPingResponse(int bytes, long seqNo, simtime_t rtt, bool isDup)
Definition: PingApp.cc:484
inet::SocketMap::findSocketFor
ISocket * findSocketFor(cMessage *msg)
Finds the socket for the given message.
Definition: SocketMap.cc:19
PacketProtocolTag
removed DscpReq Ipv4ControlInfo Ipv6ControlInfo up L3AddressInd DispatchProtocolReq L4PortInd Ipv4ControlInfo Ipv6ControlInfo down PacketProtocolTag
Definition: IUdp-gates.txt:25
inet::PingApp::pingRxSeqSignal
static simsignal_t pingRxSeqSignal
Definition: PingApp.h:71
inet::PingApp::numLostSignal
static simsignal_t numLostSignal
Definition: PingApp.h:68
inet::SocketMap::addSocket
void addSocket(ISocket *socket)
Adds the given socket.
Definition: SocketMap.cc:28
inet::units::units::B
intscale< b, 1, 8 > B
Definition: Units.h:1168
inet::PingApp::processPingResponse
virtual void processPingResponse(int identifier, int seqNumber, Packet *packet)
Definition: PingApp.cc:445
inet::ICMPv6_ECHO_REPLY
@ ICMPv6_ECHO_REPLY
Definition: Icmpv6Header_m.h:90
inet::PingApp::handleSelfMessage
virtual void handleSelfMessage(cMessage *msg)
Definition: PingApp.cc:141
inet::PingApp::startTime
simtime_t startTime
Definition: PingApp.h:45
inet::SocketMap::size
unsigned int size() const
Returns the number of sockets stored.
Definition: SocketMap.h:52
inet::PingApp::currentSocket
INetworkSocket * currentSocket
Definition: PingApp.h:53
inet::SocketMap::getMap
std::map< int, ISocket * > & getMap()
Returns the socket map.
Definition: SocketMap.h:57
inet::PingApp::sendTimeHistory
simtime_t sendTimeHistory[PING_HISTORY_SIZE]
Definition: PingApp.h:60
HopLimitReq
removed HopLimitReq
Definition: IUdp-gates.txt:11
inet::PingApp::destAddrIdx
int destAddrIdx
Definition: PingApp.h:44
inet::PingApp::numPongs
long numPongs
Definition: PingApp.h:75
inet::INITSTAGE_LOCAL
INET_API InitStage INITSTAGE_LOCAL
Initialization of local state that don't use or affect other modules includes:
inet::PingApp::getAllAddresses
virtual std::vector< L3Address > getAllAddresses()
Definition: PingApp.cc:527
inet::L3Address::getTypeName
static const char * getTypeName(AddressType t)
Definition: L3Address.cc:389
inet::PING_FIRST_ADDR
@ PING_FIRST_ADDR
Definition: PingApp_m.h:53
inet::PingApp::timer
cMessage * timer
Definition: PingApp.h:55
NUM_INIT_STAGES
#define NUM_INIT_STAGES
Definition: InitStageRegistry.h:73
inet::PingApp::outOfOrderArrivalCount
long outOfOrderArrivalCount
Definition: PingApp.h:74
inet::physicallayer::k
const double k
Definition: Qam1024Modulation.cc:14
inet::PingApp::sendSeqNo
long sendSeqNo
Definition: PingApp.h:58
inet::PingApp::stopTime
simtime_t stopTime
Definition: PingApp.h:46
inet::PingApp::count
int count
Definition: PingApp.h:43
inet::L3Address::IPv6
@ IPv6
Definition: L3Address.h:36
inet::Protocol::icmpv6
static const Protocol icmpv6
Definition: Protocol.h:72
inet::ECHO_PROTOCOL_REPLY
@ ECHO_PROTOCOL_REPLY
Definition: EchoPacket_m.h:59
inet::OperationalMixin< cSimpleModule >::delayActiveOperationFinish
virtual void delayActiveOperationFinish(simtime_t timeout)
Definition: OperationalMixinImpl.h:161
inet::OperationalMixin< cSimpleModule >::startActiveOperationExtraTimeOrFinish
virtual void startActiveOperationExtraTimeOrFinish(simtime_t extraTime)
Definition: OperationalMixinImpl.h:179
inet::PingApp::pingTxSeqSignal
static simsignal_t pingTxSeqSignal
Definition: PingApp.h:70
inet::PingApp::crcMode
CrcMode crcMode
Definition: PingApp.h:47
inet::PingApp::srcAddr
L3Address srcAddr
Definition: PingApp.h:37
inet::PingApp::cancelNextPingRequest
virtual void cancelNextPingRequest()
Definition: PingApp.cc:358
inet::PingApp::l3Echo
static const std::map< const Protocol *, const Protocol * > l3Echo
Definition: PingApp.h:63
inet::PingApp::scheduleNextPingRequest
virtual void scheduleNextPingRequest(simtime_t previous, bool withSleep)
Definition: PingApp.cc:344
inet::PingApp::socketMap
SocketMap socketMap
Definition: PingApp.h:52
inet::PingApp::sendPingRequest
virtual void sendPingRequest()
Definition: PingApp.cc:368
inet::PingApp::rttSignal
static simsignal_t rttSignal
Definition: PingApp.h:67
inet::PingApp::pid
int pid
Definition: PingApp.h:54
inet::PingApp::printPing
bool printPing
Definition: PingApp.h:48
inet::ISocket::destroy
virtual void destroy()=0
Notify the protocol that the owner of ISocket has destroyed the socket.
inet::PingApp::continuous
bool continuous
Definition: PingApp.h:49
inet::L3Address::getType
AddressType getType() const
Definition: L3Address.cc:51
inet::OperationalMixin< cSimpleModule >::refreshDisplay
virtual void refreshDisplay() const override
Definition: OperationalMixinImpl.h:200
inet::PingApp::packetSize
int packetSize
Definition: PingApp.h:39
inet::PingApp::sendIntervalPar
cPar * sendIntervalPar
Definition: PingApp.h:40
inet::INetworkSocket::bind
virtual void bind(const Protocol *protocol, L3Address localAddress)=0
Binds this socket to the given protocol and local address.
inet::INetworkSocket::setCallback
virtual void setCallback(ICallback *callback)=0
Sets a callback object, to be used with processMessage().
inet::SocketMap::removeSocket
ISocket * removeSocket(ISocket *socket)
Removes the given socket.
Definition: SocketMap.cc:34
PING_HISTORY_SIZE
#define PING_HISTORY_SIZE
Definition: PingApp.h:24
inet::ICMP_ECHO_REPLY
@ ICMP_ECHO_REPLY
Definition: IcmpHeader_m.h:85
inet::PingApp::destAddresses
std::vector< L3Address > destAddresses
Definition: PingApp.h:38
inet::PingApp::sentCount
long sentCount
Definition: PingApp.h:72
inet::PingApp::isEnabled
virtual bool isEnabled()
Definition: PingApp.cc:363
inet::Protocol::echo
static const Protocol echo
Definition: Protocol.h:125