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

📄 aodv_routing.pr.c

📁 在OPNET中实现AODV路由协议
💻 C
📖 第 1 页 / 共 5 页
字号:
		aodv_print_minor("Request has reached an intermediate node: Checking for entry", TRACE_LEV_1);
		// if node has a fresh enough (with regards to rreq_seqNb) active entry		// it replies IMMEDIATELY		if(aodv_rt_lookup_fresh_enough_active_entry(my_route_table, rreq_dest, rreq_destSeqNb) == OPC_TRUE)			{			// node has a fresh enough route
			aodv_print_minor("A fresh enough entry was found: Checking gratuitous flag", TRACE_LEV_1);			aodv_prg_print_entry(rreq_dest,TRACE_LEV_1);
			// if gratuitous mode requested, generate gratuitous RREP for destination			if(rreq_G)				{				// Trace				aodv_print_minor("Gratuitous mode was requested: Generating gratuitous RREP for destination node", TRACE_LEV_1);
				// Check if route's lifetime is long enough				if(my_route_table[rreq_dest].expi_time < (op_sim_time() + (2*rreq_hopCount+1)*NODE_TRAVERSAL_TIME))					{					aodv_print_minor("ACHTUNG ! route is not valid enough (grat requested)", TRACE_LEV_1);					}				aodv_gratuitous_rrep_pk_generate(rreq_pk_ptr);				}			else				{				// Check if route's lifetime is long enough				if(my_route_table[rreq_dest].expi_time < (op_sim_time() + (2*rreq_hopCount+1)*NODE_TRAVERSAL_TIME))					{					aodv_print_minor("ACHTUNG ! route is not valid enough", TRACE_LEV_1);					}								}			// Generate rrep for source


			aodv_print_minor("Generating RREP for source node", TRACE_LEV_1);
 
			aodv_rrep_pk_generate_from_relay(rreq_pk_ptr);			}
		else // node doesn't have any active entry for the requested 
route
			 // node forwards RREQ			{
			// Trace			aodv_print_minor("No active route was found: Forwarding RREQ to neighbors", TRACE_LEV_1);
			// Forward packet			aodv_rreq_pk_forward(rreq_pk_ptr);			}		}	}
}/*************************************************/* Check whether the BroadcastID of the request /* is greater than the last seen. If so, RREQ is /* automatically processed, and the RREQ is /* recorded in the req_seen_rep. Else, node checks/* whether RREQ packet was seen less than/* RECORD_BROADCAST_TIME seconds ago. If so, RREQ/* must be discarded. Else, it is processed.**************************************************/Boolean aodv_is_req_fresh_enough(Packet* rreq_pk_ptr)	{	// var	Boolean     result = OPC_FALSE;	int         source, dest;	double      broadcastID;		// Read RREQ fields	op_pk_nfd_get (rreq_pk_ptr,"BroadcastID",&broadcastID);
	op_pk_nfd_get (rreq_pk_ptr,"Source"     ,&source);
	op_pk_nfd_get (rreq_pk_ptr,"Dest"       ,&dest); 
	if( (req_seen_rep[source][dest].broadcast_id < broadcastID) 		||		((req_seen_rep[source][dest].broadcast_id == broadcastID) && (op_sim_time()>= req_seen_rep[source][dest].expi_time)))		{		result = OPC_TRUE;		// update RequestSeen repository
		req_seen_rep[source][ dest].broadcast_id = broadcastID;
		req_seen_rep[source][ dest].expi_time    = op_sim_time()+BROADCAST_RECORD_TIME;
		}	
	return result;	}/************************************************************/* This routine decides whether to create or update a reverse/* entry following the reception of a RREQ packet./* A special treatment is reserved to  RREQs which turn out to/* be hello messages (RREQ.dest = RREQ.source).*************************************************************/void aodv_update_or_create_reverse_entry(Packet* rreq_pk_ptr)	{	Aodv_Route_Table_Entry *entry;	int                    rreq_src_ip_addr, rreq_dest_ip_addr,	                       rreq_previous_hop_ip_addr;    int  				   rreq_src_seq_nb, rreq_dest_seq_nb;	double 				   reverse_route_lifetime = REV_ROUTE_LIFE;	int                    rreq_hop_count;	int                    create_entry      = 0;	int                    update_entry      = 0;	int                    repair_entry      = 0;	int                    generate_rerr     = 0; 	int                    result            = 0;	char                   msg[64];	Boolean                is_reverse_route_valid;	// Read RREQ packet	op_pk_nfd_get (rreq_pk_ptr,"Source"      ,&rreq_src_ip_addr);	op_pk_nfd_get (rreq_pk_ptr,"PreviousHop" ,&rreq_previous_hop_ip_addr); 
	op_pk_nfd_get (rreq_pk_ptr,"SrcSeqNb"    ,&rreq_src_seq_nb);
	op_pk_nfd_get (rreq_pk_ptr,"Dest"        ,&rreq_dest_ip_addr);	op_pk_nfd_get (rreq_pk_ptr,"HopCount"    ,&rreq_hop_count);
	op_pk_nfd_get (rreq_pk_ptr,"DestSeqNb"   ,&rreq_dest_seq_nb);		// DEBUG	aodv_prg_print_entry(rreq_src_ip_addr,TRACE_LEV_2);	// if RREQ.src = RREQ.dest, then node is a hello message	if(rreq_src_ip_addr == rreq_dest_ip_addr)		{		// trace		aodv_print_minor("RREQ turns out to be a Hello message",TRACE_LEV_1);		// Set dest field to current node addr		rreq_dest_ip_addr = my_node_addr;		op_pk_nfd_set (rreq_pk_ptr,"Dest"        ,my_node_addr);		// Set destSeqNb feld to current node source seq nb		rreq_dest_seq_nb = my_seq_nb;		op_pk_nfd_set (rreq_pk_ptr,"DestSeqNb"   ,rreq_dest_seq_nb);		// Set reverse_route_lifetime to ALLOWED_HELLO_LOSS * HELLO_INTERVAL		reverse_route_lifetime = ALLOWED_HELLO_LOSS * HELLO_INTERVAL;		}		// Check if route is valid	is_reverse_route_valid = aodv_prg_print_path(rreq_previous_hop_ip_addr,rreq_src_ip_addr, TRACE_LEV_1,light);	if(is_reverse_route_valid == OPC_FALSE)		aodv_prg_print_path(rreq_previous_hop_ip_addr,rreq_src_ip_addr, TRACE_LEV_1,full);	// if route is valid, then proceed	if(is_reverse_route_valid == OPC_TRUE)		{		// Begin		// Node update or create its entry for the source node		// only if one of the following conditions is true:		// 1. Entry does not exist		// 2. Entry active + entry.dest_seq_nb > rreq.src_seq_nb		// 3. entry active + entry.dest_seq_nb = rreq.src_seq_nb + entry.hop_count < rreq.hop_count +1		// 4. entry invalid + entry.dest_seq_nb >= rreq.src_seq_nb.		if(!my_route_table[rreq_src_ip_addr].entry_exist)			{			// Trace			aodv_print_minor("Entry does not exist: create it",TRACE_LEV_1);			// set create_entry flag			create_entry = 1;			// create entry			aodv_rt_create_entry(my_route_table, rreq_src_ip_addr);			}		else // entry exists			{			// Trace			aodv_print_minor("Entry exists",TRACE_LEV_1);					// If entry is not under repair			if(!my_route_table[rreq_src_ip_addr].repair_flag)				{				// Trace				aodv_print_minor("Entry not under repair",TRACE_LEV_1);				// if entry active				if(aodv_rt_lookup_active_entry(my_route_table, rreq_src_ip_addr) == OPC_TRUE)					{					// Trace					aodv_print_minor("Entry is active",TRACE_LEV_1);					aodv_prg_print_entry_x(rreq_src_ip_addr,TRACE_LEV_2);					// update only if:					if(my_route_table[rreq_src_ip_addr].dest_seq_nb < rreq_src_seq_nb)						{						// Trace						aodv_print_minor("New route is fresher: update entry",TRACE_LEV_1);						update_entry = 1;						}					else if( (my_route_table[rreq_src_ip_addr].dest_seq_nb == rreq_src_seq_nb) 						&& 						(my_route_table[rreq_src_ip_addr].hop_count > (rreq_hop_count +1)) )						{						// Trace						aodv_print_minor("New route is shorter: update entry",TRACE_LEV_1);						update_entry = 1;						}					}				else // entry is either invalid or marked as broken					{					// if entry invalid (equals to "not broken")					if(!my_route_table[rreq_src_ip_addr].breakage_flag)						{						// Trace						aodv_print_minor("Entry is invalid",TRACE_LEV_1);												// update only if dest seq nb is greater						if(my_route_table[rreq_src_ip_addr].dest_seq_nb <= rreq_src_seq_nb)//> -1) //<= rreq_src_seq_nb							{							// Trace							aodv_print_minor("New route is fresher: update entry",TRACE_LEV_1);														update_entry = 1;							}						}					else // entry is broken						{						// Trace						aodv_print_minor("Entry is broken",TRACE_LEV_1);						// update only if dest seq nb is greater						if(my_route_table[rreq_src_ip_addr].dest_seq_nb <= rreq_src_seq_nb)							{							// Trace							aodv_print_minor("New route is fresher: update entry",TRACE_LEV_1);							// reset breakage flag							my_route_table[rreq_src_ip_addr].breakage_flag = 0;							// Update entry							update_entry = 1;							}						}					}				}			else // entry is under repair				{				// Trace				aodv_print_minor("Entry is under repair",TRACE_LEV_1);								// Repair only if rrep_dest_seq_nb >= entry->dest_seq_nb				if(my_route_table[rreq_src_ip_addr].dest_seq_nb <= rreq_src_seq_nb)					{					// Trace					aodv_print_minor("New route is fresher: repair entry",TRACE_LEV_1);										repair_entry = 1;					// Check if new hop count is different from the former					// In such case, generate RERR with N flag set					if(my_route_table[rreq_src_ip_addr].last_hop_count != (rreq_hop_count+1))						{						generate_rerr = 1;						}					}				}			}		}	else		{		// Trace		aodv_print_minor("New route is not valid: let flow",TRACE_LEV_1);		loops++;		}	// If the flag "update_entry" or "create_entry"	// was set, than proceed as follows.	if(create_entry || update_entry || repair_entry)		{		// set result to TRUE		result = 1;		// read entry		//entry = aodv_rt_access_entry(my_route_table, rreq_src_ip_addr);		// entry should not be null		if(!my_route_table[rreq_src_ip_addr].entry_exist)			{			// Entry is nil: stop the simulation and print an error message			op_sim_end("Error @ receive rreq: trying to update an entry that does not exist","","","");			}		else			{			// schedule interruption when timeout			// this is slightly different in the 			// case of a new entry.			if(create_entry)				{				// Schedule a new intrpt				aodv_rt_entry_schedule_intrpt(my_route_table, rreq_src_ip_addr, op_sim_time() + reverse_route_lifetime);				// Trace				sprintf(msg,"Reverse route was created: Source node is %d",rreq_src_ip_addr);				aodv_print_minor(msg, TRACE_LEV_1);						}			else if(update_entry)				{				// Reschedule intrpt				aodv_rt_entry_extend_intrpt(my_route_table, rreq_src_ip_addr, op_sim_time() + reverse_route_lifetime);				// N.B: function extend updates the expiration time of an entry, only				// if the new value is greater thant the current one.				// Trace				sprintf(msg,"Reverse route was updated: Source node is %d",rreq_src_ip_addr);				aodv_print_minor(msg, TRACE_LEV_1);						}			else if(repair_entry)				{				// Reset entry flags				my_route_table[rreq_src_ip_addr].breakage_flag  = 0;				my_route_table[rreq_src_ip_addr].repair_flag    = 0;				// Reschedule intrpt				aodv_rt_entry_extend_intrpt(my_route_table, rreq_src_ip_addr, op_sim_time() + reverse_route_lifetime);				// Trace				sprintf(msg,"Reverse route was repaired: Source node is %d",rreq_src_ip_addr);				aodv_print_minor(msg, TRACE_LEV_1);						}						// Update or create entry 			my_route_table[rreq_src_ip_addr].next_hop    = rreq_previous_hop_ip_addr;			my_route_table[rreq_src_ip_addr].hop_count   = rreq_hop_count +1;			my_route_table[rreq_src_ip_addr].dest_seq_nb = rreq_src_seq_nb;			// Add -1 to the precursor list			aodv_prg_add_prec(BROADCAST, rreq_src_ip_addr);			}		}	else if(my_route_table[rreq_src_ip_addr].entry_exist)		{		// Although entry was not updated, we still		// have to extend its lifetime		// Reschedule intrpt		aodv_rt_entry_extend_intrpt(my_route_table, rreq_src_ip_addr, op_sim_time() + reverse_route_lifetime);		// Set flag		update_entry = 1;				// Trace		sprintf(msg,"Reverse route lifetime was extended: Source node is %d",rreq_src_ip_addr);		aodv_print_minor(msg, TRACE_LEV_1);				}	// Print entry	aodv_prg_print_entry(rreq_src_ip_addr, TRACE_LEV_2);		// In case, the entry's been repaired with a different hop count	// node should generate a non delete RERR packet	if(generate_rerr)		{		// trace		aodv_print_minor("New hop count is different: Generate a non delete RERR", TRACE_LEV_1);		// Generate non delete RERR pk		aodv_generate_non_delete_rerr_pk(rreq_src_ip_addr);		}		// Serve buffer in case a route has been created, updated, or repaired	if(create_entry || update_entry || repair_entry)		{		if(req_sent_rep[rreq_src_ip_addr].pending)			{			aodv_print_minor("A request was pending: cancel it, then serve buffer", TRACE_LEV_1);			// cancel pending request			aodv_cancel_pending_request(rreq_src_ip_addr);			// Print path			aodv_prg_print_path(my_node_addr,rreq_src_ip_addr, TRACE_LEV_2,light);			// Serve buffer			//aodv_buffer_serve(rreq_src_ip_addr);			}		}	// serve buffer (debug)	aodv_buffer_serve(rreq_src_ip_addr);	// Return result	//return result;	}/**********************************************************/* This function is called when a RREQ has reached its /* destination and node wants to reply./* Once the RREQ packet is g

⌨️ 快捷键说明

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