PingApp Class Reference

#include <PingApp.h>

List of all members.


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.

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


Member Function Documentation

void PingApp::initialize (  )  [protected, virtual]

00034 {
00035     // read params
00036     // (defer reading srcAddr/destAddr to when ping starts, maybe
00037     // addresses will be assigned later by some protocol)
00038     packetSize = par("packetSize");
00039     intervalp = & par("interval");
00040     hopLimit = par("hopLimit");
00041     count = par("count");
00042     startTime = par("startTime");
00043     stopTime = par("stopTime");
00044     printPing = (bool)par("printPing");
00045 
00046     // state
00047     sendSeqNo = expectedReplySeqNo = 0;
00048     WATCH(sendSeqNo);
00049     WATCH(expectedReplySeqNo);
00050 
00051     // statistics
00052     delayStat.setName("pingRTT");
00053     delayVector.setName("pingRTT");
00054     dropVector.setName("pingDrop");
00055 
00056     dropCount = outOfOrderArrivalCount = 0;
00057     WATCH(dropCount);
00058     WATCH(outOfOrderArrivalCount);
00059 
00060     // schedule first ping (use empty destAddr or stopTime<=startTime to disable)
00061     if (par("destAddr").stringValue()[0] && (stopTime==0 || stopTime>=startTime))
00062     {
00063         cMessage *msg = new cMessage("sendPing");
00064         scheduleAt(startTime, msg);
00065     }
00066 }

void PingApp::handleMessage ( cMessage *  msg  )  [protected, virtual]

00069 {
00070     if (msg->isSelfMessage())
00071     {
00072         // on first call we need to initialize
00073         if (destAddr.isUnspecified())
00074         {
00075             destAddr = IPAddressResolver().resolve(par("destAddr"));
00076             ASSERT(!destAddr.isUnspecified());
00077             srcAddr = IPAddressResolver().resolve(par("srcAddr"));
00078             EV << "Starting up: dest=" << destAddr << "  src=" << srcAddr << "\n";
00079         }
00080 
00081         // send a ping
00082         sendPing();
00083 
00084         // then schedule next one if needed
00085         scheduleNextPing(msg);
00086     }
00087     else
00088     {
00089         // process ping response
00090         processPingResponse(check_and_cast<PingPayload *>(msg));
00091     }
00092 }

void PingApp::finish (  )  [protected, virtual]

00212 {
00213     if (sendSeqNo==0)
00214     {
00215         EV << getFullPath() << ": No pings sent, skipping recording statistics and printing results.\n";
00216         recordScalar("Pings sent", sendSeqNo);
00217         return;
00218     }
00219 
00220     // record statistics
00221     recordScalar("Pings sent", sendSeqNo);
00222     recordScalar("Pings dropped", dropCount);
00223     recordScalar("Out-of-order ping arrivals", outOfOrderArrivalCount);
00224     recordScalar("Pings outstanding at end", sendSeqNo-expectedReplySeqNo);
00225 
00226     recordScalar("Ping drop rate (%)", 100 * dropCount / (double)sendSeqNo);
00227     recordScalar("Ping out-of-order rate (%)", 100 * outOfOrderArrivalCount / (double)sendSeqNo);
00228 
00229     delayStat.recordAs("Ping roundtrip delays");
00230 
00231     // print it to stdout as well
00232     cout << "--------------------------------------------------------" << endl;
00233     cout << "\t" << getFullPath() << endl;
00234     cout << "--------------------------------------------------------" << endl;
00235 
00236     cout << "sent: " << sendSeqNo
00237          << "   drop rate (%): " << (100 * dropCount / (double)sendSeqNo) << endl;
00238     cout << "round-trip min/avg/max (ms): "
00239          << (delayStat.getMin()*1000.0) << "/"
00240          << (delayStat.getMean()*1000.0) << "/"
00241          << (delayStat.getMax()*1000.0) << endl;
00242     cout << "stddev (ms): "<< (delayStat.getStddev()*1000.0)
00243          << "   variance:" << delayStat.getVariance() << endl;
00244     cout <<"--------------------------------------------------------" << endl;
00245 }

void PingApp::sendPing (  )  [protected, virtual]

Referenced by handleMessage().

00095 {
00096     EV << "Sending ping #" << sendSeqNo << "\n";
00097 
00098     char name[32];
00099     sprintf(name,"ping%ld", sendSeqNo);
00100 
00101     PingPayload *msg = new PingPayload(name);
00102     msg->setOriginatorId(getId());
00103     msg->setSeqNo(sendSeqNo);
00104     msg->setByteLength(packetSize);
00105 
00106     sendToICMP(msg, destAddr, srcAddr, hopLimit);
00107 }

void PingApp::scheduleNextPing ( cMessage *  timer  )  [protected, virtual]

Referenced by handleMessage().

00110 {
00111     simtime_t nextPing = simTime() + intervalp->doubleValue();
00112     sendSeqNo++;
00113     if ((count==0 || sendSeqNo<count) && (stopTime==0 || nextPing<stopTime))
00114         scheduleAt(nextPing, timer);
00115     else
00116         delete timer;
00117 }

void PingApp::sendToICMP ( cMessage *  payload,
const IPvXAddress destAddr,
const IPvXAddress srcAddr,
int  hopLimit 
) [protected, virtual]

Referenced by sendPing().

00120 {
00121     if (!destAddr.isIPv6())
00122     {
00123         // send to IPv4
00124         IPControlInfo *ctrl = new IPControlInfo();
00125         ctrl->setSrcAddr(srcAddr.get4());
00126         ctrl->setDestAddr(destAddr.get4());
00127         ctrl->setTimeToLive(hopLimit);
00128         msg->setControlInfo(ctrl);
00129         send(msg, "pingOut");
00130     }
00131     else
00132     {
00133         // send to IPv6
00134         IPv6ControlInfo *ctrl = new IPv6ControlInfo();
00135         ctrl->setSrcAddr(srcAddr.get6());
00136         ctrl->setDestAddr(destAddr.get6());
00137         ctrl->setHopLimit(hopLimit);
00138         msg->setControlInfo(ctrl);
00139         send(msg, "pingv6Out");
00140     }
00141 }

void PingApp::processPingResponse ( PingPayload *  msg  )  [protected, virtual]

Referenced by handleMessage().

00144 {
00145     // get src, hopCount etc from packet, and print them
00146     IPvXAddress src, dest;
00147     int msgHopCount = -1;
00148     if (dynamic_cast<IPControlInfo *>(msg->getControlInfo())!=NULL)
00149     {
00150         IPControlInfo *ctrl = (IPControlInfo *)msg->getControlInfo();
00151         src = ctrl->getSrcAddr();
00152         dest = ctrl->getDestAddr();
00153         msgHopCount = ctrl->getTimeToLive();
00154     }
00155     else if (dynamic_cast<IPv6ControlInfo *>(msg->getControlInfo())!=NULL)
00156     {
00157         IPv6ControlInfo *ctrl = (IPv6ControlInfo *)msg->getControlInfo();
00158         src = ctrl->getSrcAddr();
00159         dest = ctrl->getDestAddr();
00160         msgHopCount = ctrl->getHopLimit();
00161     }
00162 
00163     simtime_t rtt = simTime() - msg->getCreationTime();
00164 
00165     if (printPing)
00166     {
00167         cout << getFullPath() << ": reply of " << std::dec << msg->getByteLength()
00168              << " bytes from " << src
00169              << " icmp_seq=" << msg->getSeqNo() << " ttl=" << msgHopCount
00170              << " time=" << (rtt * 1000) << " msec"
00171              << " (" << msg->getName() << ")" << endl;
00172     }
00173 
00174     // update statistics
00175     countPingResponse(msg->getByteLength(), msg->getSeqNo(), rtt);
00176     delete msg;
00177 }

void PingApp::countPingResponse ( int  bytes,
long  seqNo,
simtime_t  rtt 
) [protected, virtual]

Referenced by processPingResponse().

00180 {
00181     EV << "Ping reply #" << seqNo << " arrived, rtt=" << rtt << "\n";
00182 
00183     delayStat.collect(rtt);
00184     delayVector.record(rtt);
00185 
00186     if (seqNo == expectedReplySeqNo)
00187     {
00188         // expected ping reply arrived; expect next sequence number
00189         expectedReplySeqNo++;
00190     }
00191     else if (seqNo > expectedReplySeqNo)
00192     {
00193         EV << "Jump in seq numbers, assuming pings since #" << expectedReplySeqNo << " got lost\n";
00194 
00195         // jump in the sequence: count pings in gap as lost
00196         long jump = seqNo - expectedReplySeqNo;
00197         dropCount += jump;
00198         dropVector.record(dropCount);
00199 
00200         // expect sequence numbers to continue from here
00201         expectedReplySeqNo = seqNo+1;
00202     }
00203     else // seqNo < expectedReplySeqNo
00204     {
00205         // ping arrived too late: count as out of order arrival
00206         EV << "Arrived out of order (too late)\n";
00207         outOfOrderArrivalCount++;
00208     }
00209 }


Member Data Documentation

Referenced by handleMessage(), and sendPing().

Referenced by handleMessage(), and sendPing().

int PingApp::packetSize [protected]

Referenced by initialize(), and sendPing().

cPar* PingApp::intervalp [protected]

Referenced by initialize(), and scheduleNextPing().

int PingApp::hopLimit [protected]

Referenced by initialize(), and sendPing().

int PingApp::count [protected]

Referenced by initialize(), and scheduleNextPing().

simtime_t PingApp::startTime [protected]

Referenced by initialize().

simtime_t PingApp::stopTime [protected]

Referenced by initialize(), and scheduleNextPing().

bool PingApp::printPing [protected]

Referenced by initialize(), and processPingResponse().

long PingApp::sendSeqNo [protected]

long PingApp::expectedReplySeqNo [protected]

cStdDev PingApp::delayStat [protected]

cOutVector PingApp::delayVector [protected]

Referenced by countPingResponse(), and initialize().

cOutVector PingApp::dropVector [protected]

Referenced by countPingResponse(), and initialize().

long PingApp::dropCount [protected]


The documentation for this class was generated from the following files:

Generated on Fri Mar 20 18:51:20 2009 for INET Framework for OMNeT++/OMNEST by  doxygen 1.5.5