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

📄 aodv_routing.pr.c

📁 在OPNET中实现AODV路由协议
💻 C
📖 第 1 页 / 共 5 页
字号:
				aodv_print_minor(">>> Precursor list is empty: skip to the next destination", TRACE_LEV_1);				}			}		else			{			// Trace			sprintf(msg, "Skipping destination %d", lost_node->dest_ip_addr);			aodv_print_minor(msg, TRACE_LEV_1);			}		// Skip[to next element		current_element = current_element->next;		}		// If at least one destination is still in the list	// of unreachable destinations, then rebroadcast RERR	// Else, packet is destroyed	if(aodv_list_size(new_rerr_lost_node_list) > 0)		{		// trace		sprintf(msg, "%d destinations still in the list: Broadcasting new RERR", aodv_list_size(rerr_lost_node_list));		aodv_print_minor(msg , TRACE_LEV_1);		// detroy previous packet		op_pk_destroy(rerr_pk_ptr);		// Create a new one		new_rerr_pk_ptr = op_pk_create_fmt("AODV_RERR");		// Set N field value		op_pk_nfd_set(new_rerr_pk_ptr,"N", 0);		// Set DestCount field		op_pk_nfd_set(new_rerr_pk_ptr,"DestCount", aodv_list_size(new_rerr_lost_node_list));		// Set RERR payload		op_pk_nfd_set(new_rerr_pk_ptr,"Payload",new_rerr_lost_node_list,op_prg_mem_copy_create,op_prg_mem_free,sizeof(Aodv_List));
		// Set size		op_pk_total_size_set(new_rerr_pk_ptr, 32*(1+2*aodv_list_size(new_rerr_lost_node_list)));		// Trace		aodv_print_minor("New RERR packet has been generated", TRACE_LEV_1);
		// Send to mac Layer 		aodv_pk_send(new_rerr_pk_ptr, BROADCAST);		}	else		{		// trace		aodv_print_minor("No more destination left: Destroying RERR", TRACE_LEV_1);		op_pk_destroy(rerr_pk_ptr);		}	}/**************************************************/* This routine is called to redirect the received /* RERR packet. In fact, different functions are/* called according the fact that the N flag is set/* or not.**************************************************/void aodv_rerr_pk_receive(Packet* pk_ptr)	{	int        rerr_previous_hop;	int        rerr_n_flag = 0;	// Read packet	op_pk_nfd_get(pk_ptr, "N", &rerr_n_flag);	op_pk_nfd_get(pk_ptr, "PreviousHop", &rerr_previous_hop);		// maintain local connectivity	if(CONN_SUPPORT_TYPE == NONE)		aodv_maintain_local_conn(rerr_previous_hop);	// check the N flag value	if(rerr_n_flag)		{		// trace		aodv_print_minor("N flag is set: calling appropriate function", TRACE_LEV_1);		// Process non delete RERR		aodv_non_delete_rerr_pk_process(pk_ptr);		}	else		{		// Process regular RERR		aodv_rerr_pk_process(pk_ptr);		}	}/**************************************************/* This routine receives the RERR packets whose N/* flag is set. When such a packet is received, node/* effectively processes it, only if the previous hop/* is the next hop toward the unreacheable destination/* (the one included in the list of unreachable /* destinations of the RERR packet). If so, the /* current node checks the precursor list of the entry/* corresponding to the unreachable destination./* If it is empty, RERR has reached the source node./* The latter initiates a discovery service in order/* to update its entry for the repaired destination./* Else, if the precursor list is not empty, then node/* simply forwards the RERR./* In all other cases, RERR is destroyed.**************************************************/void aodv_non_delete_rerr_pk_process(Packet* rerr_pk_ptr)	{	Aodv_Route_Table_Entry * entry;	Aodv_List * rerr_lost_node_list;	Aodv_Lost_Node * lost_node;	int              rerr_dest_count;	int              rerr_previous_hop;		// Read previous hop	op_pk_nfd_get(rerr_pk_ptr, "PreviousHop", &rerr_previous_hop);	// Read the number of unreachable destinations	// if it exceeds 1, than stop simulation	op_pk_nfd_get(rerr_pk_ptr, "DestCount", &rerr_dest_count);	// Check	if(rerr_dest_count > 1)		{		// Error: packet should contain only one unreachable dest		op_sim_end("Error @ receive non delete RERR", "More than one destinations are included in the pk","","");		}	// Continue processing	// read the list of unreachable destinations from pk	op_pk_nfd_access(rerr_pk_ptr, "Payload", &rerr_lost_node_list);	// If list is not null, then read first (and only) destination	if(rerr_lost_node_list != OPC_NIL)		{		lost_node = (Aodv_Lost_Node*) aodv_list_access_first(rerr_lost_node_list);		// read the entry for that destination in the routing table		//entry = aodv_rt_access_entry(my_route_table, lost_node->dest_ip_addr);		// Proceed, only if active entry exist, and if the next hop field is the previous hop from which		// the RERR was received		if (my_route_table[lost_node->dest_ip_addr].entry_exist 			&& 			my_route_table[lost_node->dest_ip_addr].breakage_flag != 1 			&& 			my_route_table[lost_node->dest_ip_addr].next_hop == rerr_previous_hop)			{			// Now, if the precursor_list is not empty, then set 			// the RERR packet need to be forwarded.			if( aodv_list_size(my_route_table[lost_node->dest_ip_addr].list_prec) > 0)				{				// trace				aodv_print_minor("RERR received from next hop toward destination: Forwarding packet", TRACE_LEV_1);				// forward rerr pk				aodv_pk_send(rerr_pk_ptr, BROADCAST);				}			else				{				// Packet has reached its source node.				// trace				aodv_print_minor("RERR has reached the source node", TRACE_LEV_1);				// destroy packet				op_pk_destroy(rerr_pk_ptr);				// Invalidate entry (this includes the following actions:				// 1. Copying hop count value into last hop count field				// 2. Setting hop count value to infinity				// 3. Incrementing seq nb by one.)				// trace				if(my_route_table[lost_node->dest_ip_addr].entry_exist)					{					aodv_print_minor("Invalidating entry", TRACE_LEV_1);					aodv_entry_invalidate (&my_route_table[lost_node->dest_ip_addr]);					aodv_entry_reschedule_intrpt(&my_route_table[lost_node->dest_ip_addr], op_sim_time()+DELETE_PERIOD);					// Set seq nb					my_route_table[lost_node->dest_ip_addr].dest_seq_nb = lost_node->dest_seq_nb;					// Initiate discovery 					// trace					aodv_print_minor("Buffer not empty: Initiating discovery service", TRACE_LEV_1);					aodv_initiate_discovery (lost_node->dest_ip_addr);					}				else					{					// trace					aodv_print_minor("Entry does not exist: No action taken", TRACE_LEV_1);										}				}			}		else			{			aodv_print_minor("Current node is not concerned: Packet destroyed", TRACE_LEV_1);			}		}	}/**************************************************/* This routine is called whenever a brodcast is /* received (to the exception of Hello messages)./* The idea is to update the previous hop entry in /* the routing table. The previous hop is the node/* that last brodcast the packet.**************************************************/void aodv_maintain_local_conn(int previous_hop)	{	Aodv_Route_Table_Entry * entry;	double                   lifetime = ALLOWED_HELLO_LOSS * HELLO_INTERVAL;	//aodv_prg_print_rt(TRACE_LEV_0);	if(!my_route_table[previous_hop].entry_exist)		{		aodv_print_minor("Maintain local conn: entry was created", TRACE_LEV_1);		aodv_rt_create_entry(my_route_table, previous_hop);		my_route_table[previous_hop].next_hop  = previous_hop;		my_route_table[previous_hop].dest_seq_nb = 0;		my_route_table[previous_hop].hop_count = 1;		aodv_entry_schedule_intrpt(&my_route_table[previous_hop], op_sim_time()+lifetime);		// if request was pending, then reset it and serve buffer		if(req_sent_rep[previous_hop].pending)			{			// reset request			aodv_cancel_pending_request(previous_hop);			// serve buffer			aodv_buffer_serve(previous_hop);			}		}	else if(my_route_table[previous_hop].entry_exist)		{		// read entry		//entry  = aodv_rt_access_entry(my_route_table, previous_hop);		if(my_route_table[previous_hop].next_hop != previous_hop)			{			// A shorter path was found. Node should may be 			// generate a RREQ			aodv_print_minor("Maintain local conn: a shorter path was found. What next ?", TRACE_LEV_1);			}		else 			{			// Extend lifetime			aodv_print_minor("Maintain local conn: entry already exists", TRACE_LEV_1);			aodv_rt_entry_extend_intrpt(my_route_table, previous_hop, op_sim_time()+lifetime);			}		}	// Trace	if(DEBUG) aodv_entry_print(&my_route_table[previous_hop], my_node_addr);	// serve buffer (debug)	//aodv_buffer_serve(previous_hop);	}	/**************************************************/* This routine is called when an entry is repaired/* with a different length (hop count). In this case,/* generates a RERR packet with the N flag set. The/* RERR packet includes the repaired destination IP/* address and its sequence number.**************************************************/void aodv_generate_non_delete_rerr_pk(int dest_ip_addr)	{	Aodv_Route_Table_Entry * entry;	Aodv_Lost_Node         * lost_node;	Aodv_List              * lost_node_list;	Packet                 * rerr_pk_ptr;	char                   msg[32];		// Trace	sprintf(msg,"Generating a non-delete RERR packet: unreachable node is %d",dest_ip_addr);	aodv_print_minor(msg,TRACE_LEV_1);	aodv_prg_print_entry(dest_ip_addr,TRACE_LEV_3);	// Generate RERR only if list of precursor is not empty	if( aodv_list_size(my_route_table[dest_ip_addr].list_prec) > 0)		{		lost_node = (Aodv_Lost_Node *) op_prg_mem_alloc(sizeof(Aodv_Lost_Node));		lost_node_list = aodv_list_create();		// start		lost_node->dest_ip_addr = dest_ip_addr;		lost_node->dest_seq_nb  = my_route_table[dest_ip_addr].dest_seq_nb;		// Insert lost node in the list		aodv_list_insert(lost_node_list, lost_node, dest_ip_addr);		// Create RERR pk		rerr_pk_ptr = op_pk_create_fmt("AODV_RERR");		// Set N field value		op_pk_nfd_set(rerr_pk_ptr,"N", 1);		// Set DestCount field		op_pk_nfd_set(rerr_pk_ptr,"DestCount", aodv_list_size(lost_node_list));		// Set RERR payload		op_pk_nfd_set(rerr_pk_ptr,"Payload",lost_node_list,op_prg_mem_copy_create,op_prg_mem_free,sizeof(Aodv_List));		// Set size		op_pk_total_size_set(rerr_pk_ptr, 32*(1+2*aodv_list_size(lost_node_list)));		// Trace		aodv_print_minor("RERR packet has been generated", TRACE_LEV_1);
		// Send to mac Layer 		aodv_pk_send(rerr_pk_ptr, BROADCAST);		}	else		aodv_print_minor("No RERR packet has been generated: prec list is empty", TRACE_LEV_1);	}/**************************************************/* This routine receives the aodv RREQ packet from/* the lower layer and decides whether the node/* should process the packet, discard it or simply/* forward it.**************************************************/void aodv_rreq_pk_receive(Packet* rreq_pk_ptr)
{
int                     rreq_destSeqNb;int						rreq_dest,						rreq_previous_hop,						rreq_source,                        rreq_G,						rreq_hopCount;int                     reverse_entry_exist;Aodv_Route_Table_Entry* entry;// reading packet op_pk_nfd_get (rreq_pk_ptr,"PreviousHop" ,&rreq_previous_hop);op_pk_nfd_get (rreq_pk_ptr,"Source"      ,&rreq_source);// if the previous node (the last which broadcast// the RREQ) is not the original source of the packet, // than update local connectivityif(rreq_previous_hop != rreq_source && CONN_SUPPORT_TYPE == NONE)	{	aodv_maintain_local_conn(rreq_previous_hop);	}// if req is not fresh enough (already seen), automatically// discard it. Same if the the current node is the source node// of the present packet.if(aodv_is_req_fresh_enough(rreq_pk_ptr) != OPC_TRUE || rreq_source == my_node_addr)
				
	{	// RREQ discarded		if(rreq_source == my_node_addr)		aodv_print_minor("Current node is the source of the present request: RREQ discarded", TRACE_LEV_1);
			else		aodv_print_minor("Request already seen: RREQ discarded", TRACE_LEV_1);
	// Destroy packet	op_pk_destroy(rreq_pk_ptr);
	
	}else 	{
	// Request NEVER seen OR SEEN more than BROADCAST_RECORD_TIME ago
	aodv_print_minor("Request is fresh enough: RREQ processed", TRACE_LEV_1);
	// update or create reverse entry 	aodv_print_minor("Create or update reverse entry",TRACE_LEV_2);	aodv_update_or_create_reverse_entry(rreq_pk_ptr);	// read RREQ fields	op_pk_nfd_get (rreq_pk_ptr,"Dest"        ,&rreq_dest); 
	op_pk_nfd_get (rreq_pk_ptr,"DestSeqNb"   ,&rreq_destSeqNb);
	op_pk_nfd_get (rreq_pk_ptr,"G"           ,&rreq_G);
	op_pk_nfd_get (rreq_pk_ptr,"HopCount"    ,&rreq_hopCount);
	// start processing	// If current node is the final destination	// it replies immediately	if( rreq_dest == my_node_addr) 		{
		// trace		aodv_print_minor("Request has reached its destination: Node replies", TRACE_LEV_1);
		// generate RREP from destination		aodv_rrep_pk_generate_from_destination(rreq_pk_ptr);		}	else  		{
		// Node is a relay.

⌨️ 快捷键说明

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