Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members | File Members

ping.cc

Go to the documentation of this file.
00001 // Copyright (c) 2000 by the University of Southern California
00002 // All rights reserved.
00003 //
00004 // Permission to use, copy, modify, and distribute this software and its
00005 // documentation in source and binary forms for non-commercial purposes
00006 // and without fee is hereby granted, provided that the above copyright
00007 // notice appear in all copies and that both the copyright notice and
00008 // this permission notice appear in supporting documentation. and that
00009 // any documentation, advertising materials, and other materials related
00010 // to such distribution and use acknowledge that the software was
00011 // developed by the University of Southern California, Information
00012 // Sciences Institute.  The name of the University may not be used to
00013 // endorse or promote products derived from this software without
00014 // specific prior written permission.
00015 //
00016 // THE UNIVERSITY OF SOUTHERN CALIFORNIA makes no representations about
00017 // the suitability of this software for any purpose.  THIS SOFTWARE IS
00018 // PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
00019 // INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
00020 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00021 //
00022 // Other copyrights might apply to parts of this software and are so
00023 // noted when applicable.
00024 //
00025 // $Header: /nfs/jade/vint/CVSROOT/ns-2/apps/ping.cc,v 1.5 2002/11/07 00:18:35 haldar Exp $
00026 
00027 /*
00028  * File: Code for a new 'Ping' Agent Class for the ns
00029  *       network simulator
00030  * Author: Marc Greis (greis@cs.uni-bonn.de), May 1998
00031  *
00032  * IMPORTANT: Incase of any changes made to this file , 
00033  * tutorial/examples/ping.cc file (used in Greis' tutorial) should
00034  * be updated as well.
00035  */
00036 
00037 #include "ping.h"
00038 
00039 int hdr_ping::offset_;
00040 static class PingHeaderClass : public PacketHeaderClass {
00041 public:
00042         PingHeaderClass() : PacketHeaderClass("PacketHeader/Ping", 
00043                                               sizeof(hdr_ping)) {
00044                 bind_offset(&hdr_ping::offset_);
00045         }
00046 } class_pinghdr;
00047 
00048 
00049 static class PingClass : public TclClass {
00050 public:
00051         PingClass() : TclClass("Agent/Ping") {}
00052         TclObject* create(int, const char*const*) {
00053                 return (new PingAgent());
00054         }
00055 } class_ping;
00056 
00057 
00058 PingAgent::PingAgent() : Agent(PT_PING)
00059 {
00060         bind("packetSize_", &size_);
00061 }
00062 
00063 int PingAgent::command(int argc, const char*const* argv)
00064 {
00065   if (argc == 2) {
00066     if (strcmp(argv[1], "send") == 0) {
00067       // Create a new packet
00068       Packet* pkt = allocpkt();
00069       // Access the Ping header for the new packet:
00070       hdr_ping* hdr = hdr_ping::access(pkt);
00071       // Set the 'ret' field to 0, so the receiving node
00072       // knows that it has to generate an echo packet
00073       hdr->ret = 0;
00074       // Store the current time in the 'send_time' field
00075       hdr->send_time = Scheduler::instance().clock();
00076       // Send the packet
00077       send(pkt, 0);
00078       // return TCL_OK, so the calling function knows that
00079       // the command has been processed
00080       return (TCL_OK);
00081     
00082     }
00083     
00084     else if (strcmp(argv[1], "start-WL-brdcast") == 0) {
00085       Packet* pkt = allocpkt();
00086       
00087       hdr_ip* iph = HDR_IP(pkt);
00088       hdr_ping* ph = hdr_ping::access(pkt);
00089       
00090       iph->daddr() = IP_BROADCAST;
00091       iph->dport() = iph->sport();
00092       ph->ret = 0;
00093       send(pkt, (Handler*) 0);
00094       return (TCL_OK);
00095     }
00096   }
00097   
00098   // If the command hasn't been processed by PingAgent()::command,
00099   // call the command() function for the base class
00100   return (Agent::command(argc, argv));
00101 }
00102 
00103 
00104 void PingAgent::recv(Packet* pkt, Handler*)
00105 {
00106   // Access the IP header for the received packet:
00107   hdr_ip* hdrip = hdr_ip::access(pkt);
00108   
00109   // Access the Ping header for the received packet:
00110   hdr_ping* hdr = hdr_ping::access(pkt);
00111   
00112 
00113   // check if in brdcast mode
00114   if ((u_int32_t)hdrip->daddr() == IP_BROADCAST) {
00115     if (hdr->ret == 0) {
00116       
00117       printf("Recv BRDCAST Ping REQ : at %d.%d from %d.%d\n", here_.addr_, here_.port_, hdrip->saddr(), hdrip->sport());
00118       Packet::free(pkt);
00119       
00120       // create reply
00121       Packet* pktret = allocpkt();
00122 
00123       hdr_ping* hdrret = hdr_ping::access(pktret);
00124       hdr_cmn* ch = HDR_CMN(pktret);
00125       hdr_ip* ipret = hdr_ip::access(pktret);
00126       
00127       hdrret->ret = 1;
00128       
00129       // add brdcast address
00130       ipret->daddr() = IP_BROADCAST;
00131       ipret->dport() = ipret->sport();
00132 
00133       send(pktret, 0);
00134     
00135     } else {
00136       printf("Recv BRDCAST Ping REPLY : at %d.%d from %d.%d\n", here_.addr_, here_.port_, hdrip->saddr(), hdrip->sport());
00137       Packet::free(pkt);
00138     }
00139     return;
00140   }
00141   // Is the 'ret' field = 0 (i.e. the receiving node is being pinged)?
00142   if (hdr->ret == 0) {
00143     // Send an 'echo'. First save the old packet's send_time
00144     double stime = hdr->send_time;
00145     // Discard the packet
00146     Packet::free(pkt);
00147     // Create a new packet
00148     Packet* pktret = allocpkt();
00149     // Access the Ping header for the new packet:
00150     hdr_ping* hdrret = hdr_ping::access(pktret);
00151     // Set the 'ret' field to 1, so the receiver won't send
00152     // another echo
00153     hdrret->ret = 1;
00154     // Set the send_time field to the correct value
00155     hdrret->send_time = stime;
00156     // Send the packet
00157     send(pktret, 0);
00158   } else {
00159     // A packet was received. Use tcl.eval to call the Tcl
00160     // interpreter with the ping results.
00161     // Note: In the Tcl code, a procedure
00162     // 'Agent/Ping recv {from rtt}' has to be defined which
00163     // allows the user to react to the ping result.
00164     char out[100];
00165     // Prepare the output to the Tcl interpreter. Calculate the
00166     // round trip time
00167     sprintf(out, "%s recv %d %3.1f", name(), 
00168             hdrip->src_.addr_ >> Address::instance().NodeShift_[1],
00169             (Scheduler::instance().clock()-hdr->send_time) * 1000);
00170     Tcl& tcl = Tcl::instance();
00171     tcl.eval(out);
00172     // Discard the packet
00173     Packet::free(pkt);
00174   }
00175 }
00176 
00177 

Generated on Tue Apr 20 12:14:27 2004 for NS2.26SourcesOriginal by doxygen 1.3.3