ping.cc
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:7k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * ping.cc
  3.  * Copyright (C) 2000 by the University of Southern California
  4.  * $Id: ping.cc,v 1.8 2005/08/25 18:58:01 johnh Exp $
  5.  *
  6.  * This program is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU General Public License,
  8.  * version 2, as published by the Free Software Foundation.
  9.  *
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License along
  16.  * with this program; if not, write to the Free Software Foundation, Inc.,
  17.  * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  18.  *
  19.  *
  20.  * The copyright of this module includes the following
  21.  * linking-with-specific-other-licenses addition:
  22.  *
  23.  * In addition, as a special exception, the copyright holders of
  24.  * this module give you permission to combine (via static or
  25.  * dynamic linking) this module with free software programs or
  26.  * libraries that are released under the GNU LGPL and with code
  27.  * included in the standard release of ns-2 under the Apache 2.0
  28.  * license or under otherwise-compatible licenses with advertising
  29.  * requirements (or modified versions of such code, with unchanged
  30.  * license).  You may copy and distribute such a system following the
  31.  * terms of the GNU GPL for this module and the licenses of the
  32.  * other code concerned, provided that you include the source code of
  33.  * that other code when and as the GNU GPL requires distribution of
  34.  * source code.
  35.  *
  36.  * Note that people who make modified versions of this module
  37.  * are not obligated to grant this special exception for their
  38.  * modified versions; it is their choice whether to do so.  The GNU
  39.  * General Public License gives permission to release a modified
  40.  * version without this exception; this exception also makes it
  41.  * possible to release a modified version which carries forward this
  42.  * exception.
  43.  *
  44.  */
  45. // $Header: /cvsroot/nsnam/ns-2/apps/ping.cc,v 1.8 2005/08/25 18:58:01 johnh Exp $
  46. /*
  47.  * File: Code for a new 'Ping' Agent Class for the ns
  48.  *       network simulator
  49.  * Author: Marc Greis (greis@cs.uni-bonn.de), May 1998
  50.  *
  51.  * IMPORTANT: Incase of any changes made to this file , 
  52.  * tutorial/examples/ping.cc file (used in Greis' tutorial) should
  53.  * be updated as well.
  54.  */
  55. #include "ping.h"
  56. int hdr_ping::offset_;
  57. static class PingHeaderClass : public PacketHeaderClass {
  58. public:
  59. PingHeaderClass() : PacketHeaderClass("PacketHeader/Ping", 
  60.       sizeof(hdr_ping)) {
  61. bind_offset(&hdr_ping::offset_);
  62. }
  63. } class_pinghdr;
  64. static class PingClass : public TclClass {
  65. public:
  66. PingClass() : TclClass("Agent/Ping") {}
  67. TclObject* create(int, const char*const*) {
  68. return (new PingAgent());
  69. }
  70. } class_ping;
  71. PingAgent::PingAgent() : Agent(PT_PING), seq(0), oneway(0)
  72. {
  73. bind("packetSize_", &size_);
  74. }
  75. int PingAgent::command(int argc, const char*const* argv)
  76. {
  77.   if (argc == 2) {
  78.     if (strcmp(argv[1], "send") == 0) {
  79.       // Create a new packet
  80.       Packet* pkt = allocpkt();
  81.       // Access the Ping header for the new packet:
  82.       hdr_ping* hdr = hdr_ping::access(pkt);
  83.       // Set the 'ret' field to 0, so the receiving node
  84.       // knows that it has to generate an echo packet
  85.       hdr->ret = 0;
  86.       hdr->seq = seq++;
  87.       // Store the current time in the 'send_time' field
  88.       hdr->send_time = Scheduler::instance().clock();
  89.       // Send the packet
  90.       send(pkt, 0);
  91.       // return TCL_OK, so the calling function knows that
  92.       // the command has been processed
  93.       return (TCL_OK);
  94.     
  95.     }
  96.     
  97.     else if (strcmp(argv[1], "start-WL-brdcast") == 0) {
  98.       Packet* pkt = allocpkt();
  99.       
  100.       hdr_ip* iph = HDR_IP(pkt);
  101.       hdr_ping* ph = hdr_ping::access(pkt);
  102.       
  103.       iph->daddr() = IP_BROADCAST;
  104.       iph->dport() = iph->sport();
  105.       ph->ret = 0;
  106.       send(pkt, (Handler*) 0);
  107.       return (TCL_OK);
  108.     }
  109.     else if (strcmp(argv[1], "oneway") == 0) {
  110.       oneway=1;
  111.       return (TCL_OK);
  112.     }
  113.   }
  114.   
  115.   // If the command hasn't been processed by PingAgent()::command,
  116.   // call the command() function for the base class
  117.   return (Agent::command(argc, argv));
  118. }
  119. void PingAgent::recv(Packet* pkt, Handler*)
  120. {
  121.   // Access the IP header for the received packet:
  122.   hdr_ip* hdrip = hdr_ip::access(pkt);
  123.   
  124.   // Access the Ping header for the received packet:
  125.   hdr_ping* hdr = hdr_ping::access(pkt);
  126.   
  127.   // check if in brdcast mode
  128.   if ((u_int32_t)hdrip->daddr() == IP_BROADCAST) {
  129.     if (hdr->ret == 0) {
  130.       
  131.       printf("Recv BRDCAST Ping REQ : at %d.%d from %d.%dn", here_.addr_, here_.port_, hdrip->saddr(), hdrip->sport());
  132.       Packet::free(pkt);
  133.       
  134.       // create reply
  135.       Packet* pktret = allocpkt();
  136.       hdr_ping* hdrret = hdr_ping::access(pktret);
  137.       hdr_ip* ipret = hdr_ip::access(pktret);
  138.       
  139.       hdrret->ret = 1;
  140.       
  141.       // add brdcast address
  142.       ipret->daddr() = IP_BROADCAST;
  143.       ipret->dport() = ipret->sport();
  144.       send(pktret, 0);
  145.     
  146.     } else {
  147.       printf("Recv BRDCAST Ping REPLY : at %d.%d from %d.%dn", here_.addr_, here_.port_, hdrip->saddr(), hdrip->sport());
  148.       Packet::free(pkt);
  149.     }
  150.     return;
  151.   }
  152.   // Is the 'ret' field = 0 (i.e. the receiving node is being pinged)?
  153.   if (hdr->ret == 0) {
  154.     // Send an 'echo'. First save the old packet's send_time
  155.     double stime = hdr->send_time;
  156.     int rcv_seq = hdr->seq;
  157.     // Discard the packet
  158.     Packet::free(pkt);
  159.     // Create a new packet
  160.     Packet* pktret = allocpkt();
  161.     // Access the Ping header for the new packet:
  162.     hdr_ping* hdrret = hdr_ping::access(pktret);
  163.     // Set the 'ret' field to 1, so the receiver won't send
  164.     // another echo
  165.     hdrret->ret = 1;
  166.     // Set the send_time field to the correct value
  167.     hdrret->send_time = stime;
  168.     // Added by Andrei Gurtov for one-way delay measurement.
  169.     hdrret->rcv_time = Scheduler::instance().clock();
  170.     hdrret->seq = rcv_seq;
  171.     // Send the packet
  172.     send(pktret, 0);
  173.   } else {
  174.     // A packet was received. Use tcl.eval to call the Tcl
  175.     // interpreter with the ping results.
  176.     // Note: In the Tcl code, a procedure
  177.     // 'Agent/Ping recv {from rtt}' has to be defined which
  178.     // allows the user to react to the ping result.
  179.     char out[100];
  180.     // Prepare the output to the Tcl interpreter. Calculate the
  181.     // round trip time
  182.     if (oneway) //AG
  183.        sprintf(out, "%s recv %d %d %3.1f %3.1f", name(), 
  184.     hdrip->src_.addr_ >> Address::instance().NodeShift_[1],
  185.     hdr->seq, (hdr->rcv_time - hdr->send_time) * 1000,
  186.     (Scheduler::instance().clock()-hdr->rcv_time) * 1000);
  187.     else sprintf(out, "%s recv %d %3.1f", name(), 
  188.     hdrip->src_.addr_ >> Address::instance().NodeShift_[1],
  189.     (Scheduler::instance().clock()-hdr->send_time) * 1000);
  190.     Tcl& tcl = Tcl::instance();
  191.     tcl.eval(out);
  192.     // Discard the packet
  193.     Packet::free(pkt);
  194.   }
  195. }