INET Framework for OMNeT++/OMNEST
|
#include <PingApp.h>
Protected Member Functions | |
virtual void | initialize () |
virtual void | handleMessage (cMessage *msg) |
virtual void | finish () |
virtual void | sendPing () |
virtual void | scheduleNextPing (cMessage *timer) |
virtual void | sendToICMP (cMessage *payload, const IPvXAddress &destAddr, const IPvXAddress &srcAddr, int hopLimit) |
virtual void | processPingResponse (PingPayload *msg) |
virtual void | countPingResponse (int bytes, long seqNo, simtime_t rtt) |
Protected Attributes | |
IPvXAddress | destAddr |
IPvXAddress | srcAddr |
int | packetSize |
cPar * | intervalp |
int | hopLimit |
int | count |
simtime_t | startTime |
simtime_t | stopTime |
bool | printPing |
long | sendSeqNo |
long | expectedReplySeqNo |
cStdDev | delayStat |
cOutVector | delayVector |
cOutVector | dropVector |
long | dropCount |
long | outOfOrderArrivalCount |
long | numPongs |
Generates ping requests and calculates the packet loss and round trip parameters of the replies.
See NED file for detailed description of operation.
void PingApp::countPingResponse | ( | int | bytes, |
long | seqNo, | ||
simtime_t | rtt | ||
) | [protected, virtual] |
Referenced by processPingResponse().
{ EV << "Ping reply #" << seqNo << " arrived, rtt=" << rtt << "\n"; numPongs++; delayStat.collect(rtt); delayVector.record(rtt); if (seqNo == expectedReplySeqNo) { // expected ping reply arrived; expect next sequence number expectedReplySeqNo++; } else if (seqNo > expectedReplySeqNo) { EV << "Jump in seq numbers, assuming pings since #" << expectedReplySeqNo << " got lost\n"; // jump in the sequence: count pings in gap as lost long jump = seqNo - expectedReplySeqNo; dropCount += jump; dropVector.record(dropCount); // expect sequence numbers to continue from here expectedReplySeqNo = seqNo+1; } else // seqNo < expectedReplySeqNo { // ping arrived too late: count as out of order arrival EV << "Arrived out of order (too late)\n"; outOfOrderArrivalCount++; } }
void PingApp::finish | ( | ) | [protected, virtual] |
{ if (sendSeqNo==0) { if (printPing) EV << getFullPath() << ": No pings sent, skipping recording statistics and printing results.\n"; recordScalar("Pings sent", sendSeqNo); return; } // record statistics recordScalar("Pings sent", sendSeqNo); recordScalar("Pings dropped", dropCount); recordScalar("Out-of-order ping arrivals", outOfOrderArrivalCount); recordScalar("Pings outstanding at end", sendSeqNo-expectedReplySeqNo); recordScalar("Ping drop rate (%)", 100 * dropCount / (double)sendSeqNo); recordScalar("Ping out-of-order rate (%)", 100 * outOfOrderArrivalCount / (double)sendSeqNo); delayStat.recordAs("Ping roundtrip delays"); // print it to stdout as well if (printPing) { cout << "--------------------------------------------------------" << endl; cout << "\t" << getFullPath() << endl; cout << "--------------------------------------------------------" << endl; cout << "sent: " << sendSeqNo << " drop rate (%): " << (100 * dropCount / (double)sendSeqNo) << endl; cout << "round-trip min/avg/max (ms): " << (delayStat.getMin()*1000.0) << "/" << (delayStat.getMean()*1000.0) << "/" << (delayStat.getMax()*1000.0) << endl; cout << "stddev (ms): "<< (delayStat.getStddev()*1000.0) << " variance:" << delayStat.getVariance() << endl; cout <<"--------------------------------------------------------" << endl; } }
void PingApp::handleMessage | ( | cMessage * | msg | ) | [protected, virtual] |
{ if (msg->isSelfMessage()) { // on first call we need to initialize if (destAddr.isUnspecified()) { destAddr = IPAddressResolver().resolve(par("destAddr")); ASSERT(!destAddr.isUnspecified()); srcAddr = IPAddressResolver().resolve(par("srcAddr")); EV << "Starting up: dest=" << destAddr << " src=" << srcAddr << "\n"; } // send a ping sendPing(); // then schedule next one if needed scheduleNextPing(msg); } else { // process ping response processPingResponse(check_and_cast<PingPayload *>(msg)); } }
void PingApp::initialize | ( | ) | [protected, virtual] |
{ // read params // (defer reading srcAddr/destAddr to when ping starts, maybe // addresses will be assigned later by some protocol) packetSize = par("packetSize"); intervalp = & par("interval"); hopLimit = par("hopLimit"); count = par("count"); startTime = par("startTime"); stopTime = par("stopTime"); printPing = (bool)par("printPing"); // state sendSeqNo = expectedReplySeqNo = 0; WATCH(sendSeqNo); WATCH(expectedReplySeqNo); // statistics delayStat.setName("pingRTT"); delayVector.setName("pingRTT"); dropVector.setName("pingDrop"); dropCount = outOfOrderArrivalCount = numPongs = 0; WATCH(dropCount); WATCH(outOfOrderArrivalCount); WATCH(numPongs); // schedule first ping (use empty destAddr or stopTime<=startTime to disable) if (par("destAddr").stringValue()[0] && (stopTime==0 || stopTime>=startTime)) { cMessage *msg = new cMessage("sendPing"); scheduleAt(startTime, msg); } }
void PingApp::processPingResponse | ( | PingPayload * | msg | ) | [protected, virtual] |
Referenced by handleMessage().
{ // get src, hopCount etc from packet, and print them IPvXAddress src, dest; int msgHopCount = -1; if (dynamic_cast<IPControlInfo *>(msg->getControlInfo())!=NULL) { IPControlInfo *ctrl = (IPControlInfo *)msg->getControlInfo(); src = ctrl->getSrcAddr(); dest = ctrl->getDestAddr(); msgHopCount = ctrl->getTimeToLive(); } else if (dynamic_cast<IPv6ControlInfo *>(msg->getControlInfo())!=NULL) { IPv6ControlInfo *ctrl = (IPv6ControlInfo *)msg->getControlInfo(); src = ctrl->getSrcAddr(); dest = ctrl->getDestAddr(); msgHopCount = ctrl->getHopLimit(); } simtime_t rtt = simTime() - msg->getCreationTime(); if (printPing) { cout << getFullPath() << ": reply of " << std::dec << msg->getByteLength() << " bytes from " << src << " icmp_seq=" << msg->getSeqNo() << " ttl=" << msgHopCount << " time=" << (rtt * 1000) << " msec" << " (" << msg->getName() << ")" << endl; } // update statistics countPingResponse(msg->getByteLength(), msg->getSeqNo(), rtt); delete msg; }
void PingApp::scheduleNextPing | ( | cMessage * | timer | ) | [protected, virtual] |
void PingApp::sendPing | ( | ) | [protected, virtual] |
Referenced by handleMessage().
{ EV << "Sending ping #" << sendSeqNo << "\n"; char name[32]; sprintf(name,"ping%ld", sendSeqNo); PingPayload *msg = new PingPayload(name); msg->setOriginatorId(getId()); msg->setSeqNo(sendSeqNo); msg->setByteLength(packetSize); sendToICMP(msg, destAddr, srcAddr, hopLimit); }
void PingApp::sendToICMP | ( | cMessage * | payload, |
const IPvXAddress & | destAddr, | ||
const IPvXAddress & | srcAddr, | ||
int | hopLimit | ||
) | [protected, virtual] |
Referenced by sendPing().
{ if (!destAddr.isIPv6()) { // send to IPv4 IPControlInfo *ctrl = new IPControlInfo(); ctrl->setSrcAddr(srcAddr.get4()); ctrl->setDestAddr(destAddr.get4()); ctrl->setTimeToLive(hopLimit); msg->setControlInfo(ctrl); send(msg, "pingOut"); } else { // send to IPv6 IPv6ControlInfo *ctrl = new IPv6ControlInfo(); ctrl->setSrcAddr(srcAddr.get6()); ctrl->setDestAddr(destAddr.get6()); ctrl->setHopLimit(hopLimit); msg->setControlInfo(ctrl); send(msg, "pingv6Out"); } }
int PingApp::count [protected] |
Referenced by initialize(), and scheduleNextPing().
cStdDev PingApp::delayStat [protected] |
Referenced by countPingResponse(), finish(), and initialize().
cOutVector PingApp::delayVector [protected] |
Referenced by countPingResponse(), and initialize().
IPvXAddress PingApp::destAddr [protected] |
Referenced by handleMessage(), and sendPing().
long PingApp::dropCount [protected] |
Referenced by countPingResponse(), finish(), and initialize().
cOutVector PingApp::dropVector [protected] |
Referenced by countPingResponse(), and initialize().
long PingApp::expectedReplySeqNo [protected] |
Referenced by countPingResponse(), finish(), and initialize().
int PingApp::hopLimit [protected] |
Referenced by initialize(), and sendPing().
cPar* PingApp::intervalp [protected] |
Referenced by initialize(), and scheduleNextPing().
long PingApp::numPongs [protected] |
Referenced by countPingResponse(), and initialize().
long PingApp::outOfOrderArrivalCount [protected] |
Referenced by countPingResponse(), finish(), and initialize().
int PingApp::packetSize [protected] |
Referenced by initialize(), and sendPing().
bool PingApp::printPing [protected] |
Referenced by finish(), initialize(), and processPingResponse().
long PingApp::sendSeqNo [protected] |
Referenced by finish(), initialize(), scheduleNextPing(), and sendPing().
IPvXAddress PingApp::srcAddr [protected] |
Referenced by handleMessage(), and sendPing().
simtime_t PingApp::startTime [protected] |
Referenced by initialize().
simtime_t PingApp::stopTime [protected] |
Referenced by initialize(), and scheduleNextPing().