⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aodv.cc

📁 一个无线自组网aodv路由的扩展版---AOMDV(多径路由协议)。
💻 CC
📖 第 1 页 / 共 4 页
字号:
/*    aodv.cc *//* The AODV code developed by the CMU/MONARCH group was optimized * and tuned by Samir Das and Mahesh Marina, University of Cincinnati. The  * work was partially done in Sun Microsystems. *  * The original CMU copyright is below.  *//*Copyright (c) 1997, 1998 Carnegie Mellon University.  All RightsReserved. Permission to use, copy, modify, and distribute thissoftware and its documentation is hereby granted (including forcommercial or for-profit use), provided that both the copyright noticeand this permission notice appear in all copies of the software,derivative works, or modified versions, and any portions thereof, andthat both notices appear in supporting documentation, and that creditis given to Carnegie Mellon University in all publications reportingon direct or indirect use of this code or its derivatives.ALL CODE, SOFTWARE, PROTOCOLS, AND ARCHITECTURES DEVELOPED BY THE CMUMONARCH PROJECT ARE EXPERIMENTAL AND ARE KNOWN TO HAVE BUGS, SOME OFWHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON PROVIDES THISSOFTWARE OR OTHER INTELLECTUAL PROPERTY IN ITS ``AS IS'' CONDITION,AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULARPURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITYBE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, ORCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OFSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; ORBUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCEOR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE ORINTELLECTUAL PROPERTY, EVEN IF ADVISED OF THE POSSIBILITY OF SUCHDAMAGE.Carnegie Mellon encourages (but does not require) users of thissoftware or intellectual property to return any improvements orextensions that they make, and to grant Carnegie Mellon the rights toredistribute these changes without encumbrance.*///#include <ip.h>//#include <cmu/cmu-trace.h>//#include <cmu/aodv/aodv.h>#include <cmu/aodv/aodv_packet.h>#include <random.h>#define min(a,b)        a < b ? a : b#define max(a,b)        a > b ? a : b#define CURRENT_TIME    Scheduler::instance().clock()// #define DEBUG#ifdef DEBUGstatic int extra_route_reply = 0;static int limit_route_request = 0;static int route_request = 0;#endif/*  TCL Hooks*/static class AODVHeaderClass : public PacketHeaderClass {public:        AODVHeaderClass() : PacketHeaderClass("PacketHeader/AODV",                                              AODV_HDR_LEN) { } } class_rtProtoAODV_hdr;static class AODVclass : public TclClass {public:        AODVclass() : TclClass("Agent/rtProto/AODV") {}        TclObject* create(int argc, const char*const* argv) {	  assert(argc == 5);          return (new AODV((nsaddr_t) atoi(argv[4])));        }} class_rtProtoAODV;static voidaodv_rt_failed_callback(Packet *p, void *arg) {  ((AODV*) arg)->rt_ll_failed(p);}intAODV::command(int argc, const char*const* argv) {  if(argc == 2) {  Tcl& tcl = Tcl::instance();        if(strncasecmp(argv[1], "id", 2) == 0) {      tcl.resultf("%d", index);      return TCL_OK;    }        if(strncasecmp(argv[1], "start", 2) == 0) {      btimer.handle((Event*) 0);      rqueue.limit_ = send_buffer_size_;      rqueue.timeout_ = send_buffer_timeout_;#ifdef DEBUG  fprintf(stderr, "%s: limit(%d)\ttimeout(%f)\n", __FUNCTION__, rqueue.limit_, rqueue.timeout_);  fprintf(stderr, "%s(%d): %d\n", __FUNCTION__, index, aomdv_max_paths_);  fprintf(stderr, "%s(%d): %d\n", __FUNCTION__, index, aomdv_prim_alt_path_len_diff_);#endif // DEBUG                  /*#ifndef AODV_LINK_LAYER_DETECTION      htimer.handle((Event*) 0);      ntimer.handle((Event*) 0);#endif // LINK LAYER DETECTION  */#ifdef AODV_HELLO      htimer.handle((Event*) 0);      ntimer.handle((Event*) 0);#endif // AODV HELLO      rtimer.handle((Event*) 0);      return TCL_OK;     }                 }  else if(argc == 3) {    if(strcmp(argv[1], "index") == 0) {      index = atoi(argv[2]);      return TCL_OK;    }    else if(strcmp(argv[1], "log-target") == 0) {      logtarget = (Trace*) TclObject::lookup(argv[2]);      if(logtarget == 0)	return TCL_ERROR;      return TCL_OK;    }    else if(strcmp(argv[1], "drop-target") == 0) {    int stat = rqueue.command(argc,argv);      if (stat != TCL_OK) return stat;      return Agent::command(argc, argv);    }    else if(strcmp(argv[1], "if-queue") == 0) {    ifqueue = (PriQueue*) TclObject::lookup(argv[2]);            if(ifqueue == 0)	return TCL_ERROR;      return TCL_OK;    }}  return Agent::command(argc, argv);}/*    Constructor*/AODV::AODV(nsaddr_t id) : Agent(PT_AODV),			  btimer(this), htimer(this), ntimer(this), 			  rtimer(this), lrtimer(this),			  rqueue() {   bind("off_AODV_", &off_AODV_);  send_buffer_size_ = AODV_RTQ_MAX_LEN;  bind("send_buffer_size_", &send_buffer_size_);  send_buffer_timeout_ = AODV_RTQ_TIMEOUT;  bind("send_buffer_timeout_", &send_buffer_timeout_);#ifdef AOMDV  aomdv_max_paths_ = 0;  bind("aomdv_max_paths_", &aomdv_max_paths_);  aomdv_prim_alt_path_len_diff_ = 0;  bind("aomdv_prim_alt_path_len_diff_", &aomdv_prim_alt_path_len_diff_);#endif AOMDV  index = id;  seqno = 2;  bid = 1;  LIST_INIT(&nbhead);  LIST_INIT(&bihead);  logtarget = 0;  ifqueue = 0;}voidAODV::recv(Packet *p, Handler*) {struct hdr_cmn *ch = HDR_CMN(p);struct hdr_ip *ih = HDR_IP(p); assert(initialized()); assert(p->incoming == 0); if(ch->ptype() == PT_AODV) {   ih->ttl_ -= 1;   recvAODV(p);   return; } /*  *  Must be a packet I'm originating...  */ if((ih->src_ == index) && (ch->num_forwards() == 0)) {   assert(DATA_PACKET(ch->ptype())); /*  * Add the IP Header  */   ch->size() += IP_HDR_LEN;#ifdef AOMDV   ch->aomdv_salvage_count_ = 0;#endif // AOMDV   ih->ttl_ = NETWORK_DIAMETER; } /*  *  I received a packet that I sent.  Probably  *  a routing loop.  */ else if(ih->src_ == index) {   drop(p, DROP_RTR_ROUTE_LOOP);   return; } /*  *  Packet I'm forwarding...  */ else { /*  *  Check the TTL.  If it is zero, then discard.  */   if(--ih->ttl_ == 0) {     drop(p, DROP_RTR_TTL);     return;   } } rt_resolve(p);}voidAODV::recvAODV(Packet *p) {struct hdr_aodv *ah = HDR_AODV(p);struct hdr_ip *ih = HDR_IP(p); assert(ih->sport_ == RT_PORT); assert(ih->dport_ == RT_PORT); /*  * Incoming Packets.  */ switch(ah->ah_type) { case AODVTYPE_RREQ:   recvRequest(p);   break; case AODVTYPE_RREP:   recvReply(p);   break; case AODVTYPE_RERR:   recvError(p);   break; case AODVTYPE_HELLO:   recvHello(p);   break;         default:   fprintf(stderr, "Invalid AODV type (%x)\n", ah->ah_type);   exit(1); }}/* * Data packet forwarding */voidAODV::rt_resolve(Packet *p) {struct hdr_cmn *ch = HDR_CMN(p);struct hdr_ip *ih = HDR_IP(p);aodv_rt_entry *rt; /*  *  Set the transmit failure callback.  That  *  won't change.  */ ch->xmit_failure_ = aodv_rt_failed_callback; ch->xmit_failure_data_ = (void*) this; rt = rtable.rt_lookup(ih->dst_); if(rt == 0) {   rt = rtable.rt_add(ih->dst_); } /*  * If the route is up, forward the packet   */	 if(rt->rt_flags == RTF_UP) {   forward(rt, p, NO_DELAY); } /*  *  if I am the source of the packet, then do a Route Request.  */ else if(ih->src_ == index) {   rqueue.enque(p);   sendRequest(rt->rt_dst); } /*  *	A local repair is in progress. Buffer the packet.   */ else if (rt->rt_flags == RTF_IN_REPAIR) {   rqueue.enque(p); } /*  * I am trying to forward a packet for someone else to which  * I don't have a route.  * Drop the packet and send a route error upstream  */ else { Packet *rerr = Packet::alloc(); struct hdr_aodv_error *re = HDR_AODV_ERROR(rerr); #ifdef DEBUG   fprintf(stderr, "%s: sending RERR...\n", __FUNCTION__);#endif // DEBUG   assert (rt->rt_flags == RTF_DOWN);   re->DestCount = 0;   re->unreachable_dst[re->DestCount] = rt->rt_dst;   re->unreachable_dst_seqno[re->DestCount] = rt->rt_seqno;   re->DestCount += 1;   sendError(rerr, false);   drop(p, DROP_RTR_NO_ROUTE); }}voidAODV::forward(aodv_rt_entry *rt, Packet *p, double delay) {struct hdr_cmn *ch = HDR_CMN(p);struct hdr_ip *ih = HDR_IP(p); if(ih->ttl_ == 0) {#ifdef DEBUG  fprintf(stderr, "%s: calling drop()\n", __PRETTY_FUNCTION__);#endif // DEBUG   drop(p, DROP_RTR_TTL);  return; } if (rt) {   assert(rt->rt_flags == RTF_UP);   ch->addr_type() = AF_INET;#ifndef AOMDV   ch->next_hop_ = rt->rt_nexthop;   rt->rt_expire = CURRENT_TIME + ACTIVE_ROUTE_TIMEOUT;   // CHANGE   if ((ih->src_ != index) && DATA_PACKET(ch->ptype()))   	rt->rt_error = true;   // CHANGE #else AOMDVAODV_Path *path = rt->path_find();   ch->next_hop_ = path->nexthop;   path->expire = CURRENT_TIME + ACTIVE_ROUTE_TIMEOUT;   // CHANGE   if ((ih->src_ != index) && DATA_PACKET(ch->ptype()))   	rt->rt_error = true;   // CHANGE #endif AOMDV } else { // if it is a broadcast packet   assert(ch->ptype() == PT_AODV);   assert(ih->dst_ == (nsaddr_t) IP_BROADCAST);   ch->addr_type() = AF_NONE; } if (ih->dst_ == (nsaddr_t) IP_BROADCAST) { // If it is a broadcast packet   assert(rt == 0);   /*    *  Jitter the sending of broadcast packets by 10ms    */   Scheduler::instance().schedule(target_, p,      				   0.01 * Random::uniform()); } else { // Not a broadcast packet    // CHANGE   ch->xmit_failure_ = aodv_rt_failed_callback;   ch->xmit_failure_data_ = (void*) this;   // CHANGE   if(delay > 0.0) {     Scheduler::instance().schedule(target_, p, delay);   }   else {   // Not a broadcast packet, no delay, send immediately     Scheduler::instance().schedule(target_, p, 0.);   } }}/* * Route discovery */voidAODV::sendRequest(nsaddr_t dst) {// Allocate a RREQ packet Packet *p = Packet::alloc();struct hdr_cmn *ch = HDR_CMN(p);struct hdr_ip *ih = HDR_IP(p);struct hdr_aodv_request *rq = HDR_AODV_REQUEST(p);aodv_rt_entry *rt = rtable.rt_lookup(dst);	assert(rt); 	if (rt->rt_flags == RTF_UP) {   		Packet::free((Packet *)p);   		return; 	} 	if (rt->rt_req_timeout > CURRENT_TIME) {   		Packet::free((Packet *)p);   		return; 	} 	// rt_req_cnt is the no. of times we did network-wide broadcast 	if (rt->rt_req_cnt > RREQ_RETRIES) {   		rt->rt_req_timeout = 0.0;		rt->rt_req_last_ttl = 0;   		rt->rt_req_cnt = 0; 	Packet *buf_pkt;   		while ((buf_pkt = rqueue.deque(rt->rt_dst))) {       			drop(buf_pkt, DROP_RTR_QTIMEOUT);   		}   		Packet::free((Packet *)p);   		return; 	}	rt->rt_expire = 0;	// expanding ring search: dynamic ttl evaluation	int new_ttl = 0;	if (rt->rt_req_last_ttl == 0) {	// we are about to start a new route discovery		if (rt->rt_last_hop_count == 0) new_ttl = TTL_START;		else new_ttl = rt->rt_last_hop_count + TTL_INCREMENT;	}	else {	// we are already in the midst of a route discovery		assert (rt->rt_req_last_ttl > rt->rt_last_hop_count);		if (rt->rt_req_last_ttl < TTL_THRESHOLD) new_ttl = rt->rt_req_last_ttl + TTL_INCREMENT;		else new_ttl = NETWORK_DIAMETER;	}	if (new_ttl >= NETWORK_DIAMETER) {	// network-wide broadcast		new_ttl = NETWORK_DIAMETER;		rt->rt_req_cnt += 1;	}	ih->ttl_ = new_ttl;	rt->rt_req_last_ttl = new_ttl; 	rt->rt_req_timeout = 2.0 * (double) ih->ttl_ * PerHopTime(rt);  	// PerHopTime is the roundtrip time per hop for route requests. 	// The factor 2.0 is just to be safe .. SRD 5/22/99 	if (rt->rt_req_cnt > 0)   		rt->rt_req_timeout *= rt->rt_req_cnt; 	// Also note that we are making timeouts to be larger if we have  	// done network wide broadcast before.  	rt->rt_req_timeout += CURRENT_TIME; 	// Fill out the RREQ packet  	// ch->uid() = 0; 	ch->ptype() = PT_AODV; 	ch->size() = IP_HDR_LEN + rq->size(); 	ch->iface() = -2; 	ch->error() = 0; 	ch->addr_type() = AF_NONE; 	ih->src_ = index; 	ih->dst_ = IP_BROADCAST; 	ih->sport_ = RT_PORT; 	ih->dport_ = RT_PORT;	 	// Fill up some more fields.  	rq->rq_type = AODVTYPE_RREQ; 	rq->rq_bcast_id = bid++; 	rq->rq_hop_count = 0; 	rq->rq_dst = dst; 	rq->rq_dst_seqno = (rt ? rt->rt_seqno : 0); 	rq->rq_src = index;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -