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

📄 aodv.cc

📁 fso antenna model for ns2
💻 CC
📖 第 1 页 / 共 3 页
字号:
		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.	*/	else {		Packet *rerr = Packet::alloc();		struct hdr_aodv_error *re = HDR_AODV_ERROR(rerr);		/* 		* For now, drop the packet and send error upstream.		* Now the route errors are broadcast to upstream		* neighbors - Mahesh 09/11/99		*/			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;#ifdef DEBUG		fprintf(stderr, "%s: sending RERR...\n", __FUNCTION__);#endif		sendError(rerr, false);		drop(p, DROP_RTR_NO_ROUTE);	}}voidAODV::rt_purge() {	aodv_rt_entry *rt, *rtn;	double now = CURRENT_TIME;	double delay = 0.0;	Packet *p;	for(rt = rtable.head(); rt; rt = rtn) {  // for each rt entry		rtn = rt->rt_link.le_next;		if ((rt->rt_flags == RTF_UP) && (rt->rt_expire < now)) {			// if a valid route has expired, purge all packets from 			// send buffer and invalidate the route.                    			assert(rt->rt_hops != INFINITY2);			while((p = rqueue.deque(rt->rt_dst))) {#ifdef DEBUG				fprintf(stderr, "%s: calling drop()\n",					__FUNCTION__);#endif // DEBUG				drop(p, DROP_RTR_NO_ROUTE);			}			rt->rt_seqno++;			assert (rt->rt_seqno%2);			rt_down(rt);		}		else if (rt->rt_flags == RTF_UP) {			// If the route is not expired,			// and there are packets in the sendbuffer waiting,			// forward them. This should not be needed, but this extra 			// check does no harm.			assert(rt->rt_hops != INFINITY2);			while((p = rqueue.deque(rt->rt_dst))) {				forward (rt, p, delay);				delay += ARP_DELAY;			}		} 		else if (rqueue.find(rt->rt_dst))			// If the route is down and 			// if there is a packet for this destination waiting in			// the sendbuffer, then send out route request. sendRequest			// will check whether it is time to really send out request			// or not.			// This may not be crucial to do it here, as each generated 			// packet will do a sendRequest anyway.			sendRequest(rt->rt_dst); 	}}/*Packet Reception Routines*/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);	// XXXXX NOTE: use of incoming flag has been depracated; In order to track direction of pkt flow, direction_ in hdr_cmn is used instead. see packet.h for details.	if(ch->ptype() == PT_AODV) {		ih->ttl_ -= 1;		recvAODV(p);		return;	}	/*	*  Must be a packet I'm originating...	*/	if((ih->saddr() == index) && (ch->num_forwards() == 0)) {		/*		* Add the IP Header		*/		ch->size() += IP_HDR_LEN;		// Added by Parag Dadhania && John Novatnack to handle broadcasting		if ( (u_int32_t)ih->daddr() != IP_BROADCAST)			ih->ttl_ = NETWORK_DIAMETER;	}	/*	*  I received a packet that I sent.  Probably	*  a routing loop.	*/	else if(ih->saddr() == 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;		}	}	// Added by Parag Dadhania && John Novatnack to handle broadcasting	if ( (u_int32_t)ih->daddr() != IP_BROADCAST)		rt_resolve(p);	else		forward((aodv_rt_entry*) 0, p, NO_DELAY);}voidAODV::recvAODV(Packet *p) {	struct hdr_aodv *ah = HDR_AODV(p);	assert(HDR_IP(p)->sport() == RT_PORT);	assert(HDR_IP(p)->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);	}}voidAODV::recvRequest(Packet *p){	struct hdr_ip *ih = HDR_IP(p);	struct hdr_aodv_request *rq = HDR_AODV_REQUEST(p);	struct hdr_ll *llh = HDR_LL(p);	aodv_rt_entry *rt;	/*	* Drop if:	*      - I'm the source	*      - I recently heard this request.	*/	if(rq->rq_src == index)	{#ifdef DEBUG		fprintf(stderr, "%s: got my own REQUEST\n", __FUNCTION__);#endif // DEBUG		Packet::free(p);		return;	} 	if (id_lookup(rq->rq_src, rq->rq_bcast_id)) {#ifdef DEBUG		fprintf(stderr, "%s: discarding request\n", __FUNCTION__);#endif // DEBUG		Packet::free(p);		return;	}	/*	* Cache the broadcast ID	*/	id_insert(rq->rq_src, rq->rq_bcast_id);	/* 	* We are either going to forward the REQUEST or generate a	* REPLY. Before we do anything, we make sure that the REVERSE	* route is in the route table.	*/	aodv_rt_entry *rt0; // rt0 is the reverse route 	rt0 = rtable.rt_lookup(rq->rq_src);	if(rt0 == 0) { /* if not in the route table */		// create an entry for the reverse route.		rt0 = rtable.rt_add(rq->rq_src);	}	rt0->rt_expire = max(rt0->rt_expire, (CURRENT_TIME + REV_ROUTE_LIFE));	rt0->rt_interface = llh->RxLL_;	if ( (rq->rq_src_seqno > rt0->rt_seqno ) ||		((rq->rq_src_seqno == rt0->rt_seqno) && 		(rq->rq_hop_count < rt0->rt_hops)) )	{		// If we have a fresher seq no. or lesser #hops for the 		// same seq no., update the rt entry. Else don't bother.		rt_update(rt0, rq->rq_src_seqno, rq->rq_hop_count, ih->saddr(), max(rt0->rt_expire, (CURRENT_TIME + REV_ROUTE_LIFE)) );		if (rt0->rt_req_timeout > 0.0)		{			// Reset the soft state and 			// Set expiry time to CURRENT_TIME + ACTIVE_ROUTE_TIMEOUT			// This is because route is used in the forward direction,			// but only sources get benefited by this change			rt0->rt_req_cnt = 0;			rt0->rt_req_timeout = 0.0; 			rt0->rt_req_last_ttl = rq->rq_hop_count;			rt0->rt_expire = CURRENT_TIME + ACTIVE_ROUTE_TIMEOUT;		}		/* Find out whether any buffered packet can benefit from the 		* reverse route.		* May need some change in the following code - Mahesh 09/11/99		*/		assert (rt0->rt_flags == RTF_UP);		Packet *buffered_pkt;		while ((buffered_pkt = rqueue.deque(rt0->rt_dst)))		{			if (rt0 && (rt0->rt_flags == RTF_UP))			{				assert(rt0->rt_hops != INFINITY2);				forward(rt0, buffered_pkt, NO_DELAY);			}		}	} 	// End for putting reverse route in rt table	/*	* We have taken care of the reverse route stuff.	* Now see whether we can send a route reply. 	*/	rt = rtable.rt_lookup(rq->rq_dst);	// First check if I am the destination ..	if(rq->rq_dst == index)	{#ifdef DEBUG	fprintf(stderr, "%d - %s: destination sending reply\n", index, __FUNCTION__);#endif // DEBUG		// Just to be safe, I use the max. Somebody may have		// incremented the dst seqno.		seqno = max(seqno, rq->rq_dst_seqno)+1;		if (seqno%2) seqno++;		sendReply(rq->rq_src,           // IP Destination			1,                    // Hop Count			index,                // Dest IP Address			seqno,                // Dest Sequence Num			MY_ROUTE_TIMEOUT,     // Lifetime			rq->rq_timestamp);    // timestamp		Packet::free(p);	}	// I am not the destination, but I may have a fresh enough route.	else if (rt && (rt->rt_hops != INFINITY2) && 		(rt->rt_seqno >= rq->rq_dst_seqno) )	{		//assert (rt->rt_flags == RTF_UP);		assert(rq->rq_dst == rt->rt_dst);		//assert ((rt->rt_seqno%2) == 0);	// is the seqno even?		sendReply(rq->rq_src,			rt->rt_hops + 1,			rq->rq_dst,			rt->rt_seqno,			(u_int32_t) (rt->rt_expire - CURRENT_TIME),			//   rt->rt_expire - CURRENT_TIME,			rq->rq_timestamp);		// Insert nexthops to RREQ source and RREQ destination in the		// precursor lists of destination and source respectively		rt->pc_insert(rt0->rt_nexthop); // nexthop to RREQ source		rt0->pc_insert(rt->rt_nexthop); // nexthop to RREQ destination#ifdef RREQ_GRAT_RREP  		sendReply(rq->rq_dst,			rq->rq_hop_count,			rq->rq_src,			rq->rq_src_seqno,			(u_int32_t) (rt->rt_expire - CURRENT_TIME),								//             rt->rt_expire - CURRENT_TIME,			rq->rq_timestamp);#endif		// TODO: send grat RREP to dst if G flag set in RREQ using rq->rq_src_seqno, rq->rq_hop_counT		// DONE: Included gratuitous replies to be sent as per IETF aodv draft specification. As of now, G flag has not been dynamically used and is always set or reset in aodv-packet.h --- Anant Utgikar, 09/16/02.		Packet::free(p);	}	/*	* Can't reply. So forward the  Route Request	*/	else	{		ih->saddr() = index;		ih->daddr() = IP_BROADCAST;		rq->rq_hop_count += 1;		// Maximum sequence number seen en route		if (rt) rq->rq_dst_seqno = max(rt->rt_seqno, rq->rq_dst_seqno);		forward((aodv_rt_entry*) 0, p, DELAY);	}}voidAODV::recvReply(Packet *p){	//struct hdr_cmn *ch = HDR_CMN(p);	struct hdr_ip *ih = HDR_IP(p);	struct hdr_aodv_reply *rp = HDR_AODV_REPLY(p);	struct hdr_ll *llh = HDR_LL(p);	aodv_rt_entry *rt;	char suppress_reply = 0;	double delay = 0.0;#ifdef DEBUG	fprintf(stderr, "%d - %s: received a REPLY\n", index, __FUNCTION__);#endif // DEBUG	/*	*  Got a reply. So reset the "soft state" maintained for 	*  route requests in the request table. We don't really have	*  have a separate request table. It is just a part of the	*  routing table itself. 	*/	// Note that rp_dst is the dest of the data packets, not the	// the dest of the reply, which is the src of the data packets.	rt = rtable.rt_lookup(rp->rp_dst);	/*	*  If I don't have a rt entry to this host... adding	*/	if(rt == 0)	{		rt = rtable.rt_add(rp->rp_dst);	}		rt->rt_interface = llh->RxLL_;	/*	* Add a forward route table entry... here I am following 	* Perkins-Royer AODV paper almost literally - SRD 5/99	*/	if ( (rt->rt_seqno < rp->rp_dst_seqno) ||   // newer route 		((rt->rt_seqno == rp->rp_dst_seqno) &&  		(rt->rt_hops > rp->rp_hop_count)) )	{ // shorter or better route		// Update the rt entry 		rt_update(rt, rp->rp_dst_seqno, rp->rp_hop_count,			rp->rp_src, CURRENT_TIME + rp->rp_lifetime);		// reset the soft state		rt->rt_req_cnt = 0;		rt->rt_req_timeout = 0.0; 		rt->rt_req_last_ttl = rp->rp_hop_count;		if (ih->daddr() == index) 		{ // If I am the original source			// Update the route discovery latency statistics			// rp->rp_timestamp is the time of request origination			rt->rt_disc_latency[(unsigned char)rt->hist_indx] = (CURRENT_TIME - rp->rp_timestamp)				/ (double) rp->rp_hop_count;			// increment indx for next time			rt->hist_indx = (rt->hist_indx + 1) % MAX_HISTORY;		}			/*		* Send all packets queued in the sendbuffer destined for		* this destination. 		* XXX - observe the "second" use of p.		*/		Packet *buf_pkt;		while((buf_pkt = rqueue.deque(rt->rt_dst))) {			if(rt->rt_hops != INFINITY2) {				assert (rt->rt_flags == RTF_UP);				// Delay them a little to help ARP. Otherwise ARP 				// may drop packets. -SRD 5/23/99				forward(rt, buf_pkt, delay);				delay += ARP_DELAY;			}		}	}	else	{		suppress_reply = 1;	}	/*	* If reply is for me, discard it.	*/	if(ih->daddr() == index || suppress_reply)	{		Packet::free(p);	}	/*	* Otherwise, forward the Route Reply.	*/	else	{		// Find the rt entry		aodv_rt_entry *rt0 = rtable.rt_lookup(ih->daddr());		// If the rt is up, forward		if(rt0 && (rt0->rt_hops != INFINITY2))		{			//assert (rt0->rt_flags == RTF_UP);			rp->rp_hop_count += 1;			rp->rp_src = index;			forward(rt0, p, NO_DELAY);			// Insert the nexthop towards the RREQ source to 			// the precursor list of the RREQ destination			rt->pc_insert(rt0->rt_nexthop); // nexthop to RREQ source		}		else		{			// I don't know how to forward .. drop the reply. #ifdef DEBUG			fprintf(stderr, "%s: dropping Route Reply\n", __FUNCTION__);#endif // DEBUG			drop(p, DROP_RTR_NO_ROUTE);		}	}}voidAODV::recvError(Packet *p) {	struct hdr_ip *ih = HDR_IP(p);	struct hdr_aodv_error *re = HDR_AODV_ERROR(p);	aodv_rt_entry *rt;	u_int8_t i;	Packet *rerr = Packet::alloc();	struct hdr_aodv_error *nre = HDR_AODV_ERROR(rerr);

⌨️ 快捷键说明

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