ns-tutorial/examples/ping.cc

Go to the documentation of this file.
00001 /*
00002  * File: Code for a new 'Ping' Agent Class for the ns
00003  *       network simulator
00004  * Author: Marc Greis (greis@cs.uni-bonn.de), May 1998
00005  *
00006  */
00007 
00008 
00009 #include "ping.h"
00010 
00011 
00012 static class PingHeaderClass : public PacketHeaderClass {
00013 public:
00014   PingHeaderClass() : PacketHeaderClass("PacketHeader/Ping", 
00015                     sizeof(hdr_ping)) {}
00016 } class_pinghdr;
00017 
00018 
00019 static class PingClass : public TclClass {
00020 public:
00021   PingClass() : TclClass("Agent/Ping") {}
00022   TclObject* create(int, const char*const*) {
00023     return (new PingAgent());
00024   }
00025 } class_ping;
00026 
00027 
00028 PingAgent::PingAgent() : Agent(PT_PING)
00029 {
00030   bind("packetSize_", &size_);
00031   bind("off_ping_", &off_ping_);
00032 }
00033 
00034 
00035 int PingAgent::command(int argc, const char*const* argv)
00036 {
00037   if (argc == 2) {
00038     if (strcmp(argv[1], "send") == 0) {
00039       // Create a new packet
00040       Packet* pkt = allocpkt();
00041       // Access the Ping header for the new packet:
00042       hdr_ping* hdr = (hdr_ping*)pkt->access(off_ping_);
00043       // Set the 'ret' field to 0, so the receiving node knows
00044       // that it has to generate an echo packet
00045       hdr->ret = 0;
00046       // Store the current time in the 'send_time' field
00047       hdr->send_time = Scheduler::instance().clock();
00048       // Send the packet
00049       send(pkt, 0);
00050       // return TCL_OK, so the calling function knows that the
00051       // command has been processed
00052       return (TCL_OK);
00053     }
00054   }
00055   // If the command hasn't been processed by PingAgent()::command,
00056   // call the command() function for the base class
00057   return (Agent::command(argc, argv));
00058 }
00059 
00060 
00061 void PingAgent::recv(Packet* pkt, Handler*)
00062 {
00063   // Access the IP header for the received packet:
00064   hdr_ip* hdrip = (hdr_ip*)pkt->access(off_ip_);
00065   // Access the Ping header for the received packet:
00066   hdr_ping* hdr = (hdr_ping*)pkt->access(off_ping_);
00067   // Is the 'ret' field = 0 (i.e. the receiving node is being pinged)?
00068   if (hdr->ret == 0) {
00069     // Send an 'echo'. First save the old packet's send_time
00070     double stime = hdr->send_time;
00071     // Discard the packet
00072     Packet::free(pkt);
00073     // Create a new packet
00074     Packet* pktret = allocpkt();
00075     // Access the Ping header for the new packet:
00076     hdr_ping* hdrret = (hdr_ping*)pktret->access(off_ping_);
00077     // Set the 'ret' field to 1, so the receiver won't send another echo
00078     hdrret->ret = 1;
00079     // Set the send_time field to the correct value
00080     hdrret->send_time = stime;
00081     // Send the packet
00082     send(pktret, 0);
00083   } else {
00084     // A packet was received. Use tcl.eval to call the Tcl
00085     // interpreter with the ping results.
00086     // Note: In the Tcl code, a procedure 'Agent/Ping recv {from rtt}'
00087     // has to be defined which allows the user to react to the ping
00088     // result.
00089     char out[100];
00090     // Prepare the output to the Tcl interpreter. Calculate the round
00091     // trip time
00092     sprintf(out, "%s recv %d %3.1f", name(), 
00093             hdrip->src_ >> Address::instance().NodeShift_[1], 
00094         (Scheduler::instance().clock()-hdr->send_time) * 1000);
00095     Tcl& tcl = Tcl::instance();
00096     tcl.eval(out);
00097     // Discard the packet
00098     Packet::free(pkt);
00099   }
00100 }
00101 
00102 

Generated on Tue Mar 6 16:47:49 2007 for ns2 Network Simulator 2.29 by  doxygen 1.4.6