sr_forwarder.cc

Go to the documentation of this file.
00001 
00002 /*
00003  * sr_forwarder.cc
00004  * Copyright (C) 2000 by the University of Southern California
00005  * $Id: sr_forwarder.cc,v 1.2 2005/08/25 18:58:05 johnh Exp $
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License,
00009  * version 2, as published by the Free Software Foundation.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License along
00017  * with this program; if not, write to the Free Software Foundation, Inc.,
00018  * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
00019  *
00020  *
00021  * The copyright of this module includes the following
00022  * linking-with-specific-other-licenses addition:
00023  *
00024  * In addition, as a special exception, the copyright holders of
00025  * this module give you permission to combine (via static or
00026  * dynamic linking) this module with free software programs or
00027  * libraries that are released under the GNU LGPL and with code
00028  * included in the standard release of ns-2 under the Apache 2.0
00029  * license or under otherwise-compatible licenses with advertising
00030  * requirements (or modified versions of such code, with unchanged
00031  * license).  You may copy and distribute such a system following the
00032  * terms of the GNU GPL for this module and the licenses of the
00033  * other code concerned, provided that you include the source code of
00034  * that other code when and as the GNU GPL requires distribution of
00035  * source code.
00036  *
00037  * Note that people who make modified versions of this module
00038  * are not obligated to grant this special exception for their
00039  * modified versions; it is their choice whether to do so.  The GNU
00040  * General Public License gives permission to release a modified
00041  * version without this exception; this exception also makes it
00042  * possible to release a modified version which carries forward this
00043  * exception.
00044  *
00045  */
00046 //
00047 // Other copyrights might apply to parts of this software and are so
00048 // noted when applicable.
00049 //
00050 // Ported from CMU/Monarch's code, appropriate copyright applies.  
00051 /* -*- c++ -*-
00052    
00053    sr_forwarder.cc
00054    source route forwarder
00055 
00056    */
00057 
00058 
00059 #include <object.h>
00060 #include <packet.h>
00061 #include <ip.h>
00062 #include <mac.h>
00063 #include "hdr_sr.h"
00064 #include "dsr_proto.h"
00065 #include "routecache.h"
00066 #include "requesttable.h"
00067 #include "sr_forwarder.h"
00068 
00069 /*===========================================================================
00070   static classes for OTcl
00071 ---------------------------------------------------------------------------*/
00072 static class SRForwarderClass : public TclClass {
00073 public:
00074   SRForwarderClass() : TclClass("SRForwarder") {}
00075   TclObject* create(int, const char*const*) {
00076     return (new SRForwarder);
00077   }
00078 } class_srforwarder;
00079 
00080 
00081 /*===========================================================================
00082   Member functions
00083 ---------------------------------------------------------------------------*/
00084 SRForwarder::SRForwarder()
00085 {
00086   target_ = 0;
00087   route_agent_ = 0;
00088   tracetarget = 0;
00089   
00090   bind("off_sr_", &off_sr_);
00091   bind("off_ll_", &off_ll_);
00092   bind("off_mac_", &off_mac_);
00093   bind("off_ip_", &off_ip_);
00094 
00095 }
00096 
00097 int
00098 SRForwarder::command(int argc, const char*const* argv)
00099 {
00100   Tcl& tcl = Tcl::instance();
00101 
00102   if (argc == 2) 
00103     {
00104       if (strcmp(argv[1], "target") == 0) {
00105     if (target_ != 0)
00106       tcl.result(target_->name());
00107     return (TCL_OK);
00108       }
00109       if (strcmp(argv[1], "routeagent") == 0) {
00110     if (route_agent_ != 0)
00111       tcl.result(route_agent_->name());
00112     return (TCL_OK);
00113       }
00114     }
00115   else if(argc == 3) 
00116     {
00117       TclObject *obj;
00118       
00119       if( (obj = TclObject::lookup(argv[2])) == 0) {
00120     fprintf(stderr, "SRForwarder: %s lookup of %s failed\n", argv[1],
00121         argv[2]);
00122     return TCL_ERROR;
00123       }
00124 
00125       if (strcasecmp(argv[1], "tracetarget") == 0) 
00126     {
00127       tracetarget = (Trace*) obj;
00128       return TCL_OK;
00129     }
00130       else if (strcasecmp(argv[1], "routecache") == 0) 
00131     {
00132       routecache_ = (RouteCache*) obj;
00133       return TCL_OK;
00134     }
00135       else if (strcasecmp(argv[1], "target") == 0) 
00136     {
00137       target_ = (NsObject*) obj;
00138       return TCL_OK;
00139     }
00140       else if (strcasecmp(argv[1], "routeagent") == 0) 
00141     {
00142       route_agent_ = (DSRProto*) obj;
00143       return TCL_OK;
00144     }
00145     }
00146   
00147   return NsObject::command(argc, argv);
00148 }
00149 
00150 void
00151 SRForwarder::handlePktWithoutSR(Packet *p)
00152 {
00153   hdr_sr *srh = hdr_sr::access(p);
00154   hdr_ip *iph = hdr_ip::access(p);
00155   //hdr_cmn *cmh =  hdr_cmn::access(p);
00156   Path path;
00157 
00158   /* check route cache for source route for this packet */
00159   //if (routecache_->findRoute(ID(iph->daddr()>>8,::IP),path))
00160   if (routecache_->findRoute(ID(iph->daddr(),::IP),path,0))
00161     {
00162       srh->init();
00163       path.fillSR(srh);
00164       sprintf(tracetarget->pt_->buffer(),
00165           "$hit %g originating 0x%x -> 0x%x %s", 
00166           Scheduler::instance().clock(),
00167           iph->saddr(), iph->daddr(), srh->dump());
00168       tracetarget->pt_->dump();
00169       this->recv(p,0);      // send back to forwarder to send this out
00170       return;
00171     }
00172   
00173   /* if not found, give packet to routing protocol */
00174   sprintf(tracetarget->pt_->buffer(),
00175       "dfu %g srforwarder: %s no route to 0x%x", 
00176       Scheduler::instance().clock(),
00177       routecache_->net_id.dump(), iph->daddr());
00178   tracetarget->pt_->dump();
00179 
00180   route_agent_->noRouteForPacket(p);
00181 }
00182 
00183 void
00184 SRForwarder::recv(Packet* p, Handler* callback)
00185 {
00186   hdr_sr *srh =  (hdr_sr*)p->access(off_sr_);
00187 
00188   assert(tracetarget != 0);
00189 
00190   if (!srh->valid())
00191     {
00192       handlePktWithoutSR(p);
00193       return;
00194     }
00195 
00196   /* forward as per source route */
00197   hdr_ip *iph = hdr_ip::access(p);
00198   hdr_cmn *cmnh =  hdr_cmn::access(p);
00199   
00200   if (srh->route_request())
00201     { /* just broadcast */
00202       cmnh->next_hop() = MAC_BROADCAST;
00203       cmnh->addr_type() = NS_AF_ILINK;
00204       target_->recv(p, (Handler*)0);
00205       return;     
00206     }
00207   
00208   /* it must be a normal data packet with a source route */
00209   if (tracetarget)
00210     {
00211       sprintf(tracetarget->pt_->buffer(),
00212           "F %g 0x%x -> 0x%x via 0x%x %s", 
00213           Scheduler::instance().clock(),
00214           iph->saddr(), iph->daddr(), srh->get_next_addr(), srh->dump());
00215       tracetarget->pt_->dump();
00216     }
00217   
00218   cmnh->next_hop() = srh->get_next_addr();
00219   cmnh->addr_type() = NS_AF_INET;
00220   srh->cur_addr() = srh->cur_addr() + 1;
00221   target_->recv(p, (Handler*)0);
00222   return;
00223 }

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