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

📄 aodv_rrep.c

📁 支持IPv6的adov路由协议(本人修改后)
💻 C
字号:
/***************************************************************************** * * Copyright (C) 2001 Uppsala University & Ericsson AB. * Copyright (C) 2003 Simon Fraser University and NewMIC * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA * * Authors: Erik Nordstr鰉, <erik.nordstrom@it.uu.se> *        : Peter Lee       <peter.lee@shaw.ca> *           * *****************************************************************************/#include <netinet/in.h>#ifdef NS_PORT#include "aodv-uu.h"#else#include "aodv_rrep.h"#include "aodv_hello.h"#include "routing_table.h"#include "packet_queue.h"#include "aodv_timeout.h"#include "timer_queue.h"#include "aodv_socket.h"#include "seek_list.h"#include "defs.h"#include "debug.h"#include "params.h"#include "ipv6_utils.h"#include "address_conf.h"#endifextern int internet_gw_mode;//PL:#ifdef _IPV6RREP *NS_CLASS rrep_create(u_int8_t flags,			   u_int8_t prefix,			   u_int8_t hcnt,			   struct in6_addr dest_addr,			   u_int32_t dest_seqno,			   struct in6_addr orig_addr, u_int32_t life)#elseRREP *NS_CLASS rrep_create(u_int8_t flags,			   u_int8_t prefix,			   u_int8_t hcnt,			   u_int32_t dest_addr,			   u_int32_t dest_seqno,			   u_int32_t orig_addr, u_int32_t life)#endif /* _IPV6 */{    RREP *rrep;    rrep = (RREP *) aodv_socket_new_msg();    rrep->type = AODV_RREP;    rrep->res1 = 0;    rrep->res2 = 0;    rrep->prefix = prefix;    rrep->hcnt = hcnt;    //PL:#ifdef _IPV6    copy_in6_addr(&rrep->dest_addr, &dest_addr);    rrep->dest_seqno = htonl(dest_seqno);    copy_in6_addr(&rrep->orig_addr, &orig_addr);    rrep->lifetime = htonl(life);#else    rrep->dest_addr = htonl(dest_addr);    rrep->dest_seqno = htonl(dest_seqno);    rrep->orig_addr = htonl(orig_addr);    rrep->lifetime = htonl(life);#endif /* _IPV6 */    if (flags & RREP_INTERNET)    	rrep->i = 1;    if (flags & RREP_REPAIR)	rrep->r = 1;    if (flags & RREP_ACK)	rrep->a = 1;    /* Don't print information about hello messages... */#ifdef DEBUG_OUTPUT    //PL:#ifdef _IPV6    if ((memcmp(&dest_addr, &orig_addr, sizeof(struct in6_addr)) != 0 ))      {	DEBUG(LOG_DEBUG, 0, "Assembled RREP:");	log_pkt_fields((AODV_msg *) rrep);      }	else{/*ZJH*/	printf("ZJH:HELLO message created!!!\n");	log_pkt_fields((AODV_msg *)rrep);	}/*ZJH*/#else    if (dest_addr != orig_addr) {	DEBUG(LOG_DEBUG, 0, "Assembled RREP:");	log_pkt_fields((AODV_msg *) rrep);    }#endif /* _IPV6 */#endif /* DEBUG_OUTPUT */    return rrep;}RREP_ack *NS_CLASS rrep_ack_create(){    RREP_ack *rrep_ack;    rrep_ack = (RREP_ack *) aodv_socket_new_msg();    rrep_ack->type = AODV_RREP_ACK;    DEBUG(LOG_DEBUG, 0, "Assembled RREP_ack");    return rrep_ack;}//PL:#ifdef _IPV6void NS_CLASS rrep_ack_process(RREP_ack * rrep_ack, int rrep_acklen,			       struct in6_addr ip_src, struct in6_addr ip_dst)#elsevoid NS_CLASS rrep_ack_process(RREP_ack * rrep_ack, int rrep_acklen,			       u_int32_t ip_src, u_int32_t ip_dst)#endif /* _IPV6 */{    rt_table_t *rt_entry;    rt_entry = rt_table_find(ip_src);	//PL:#ifdef _IPV6    if (rt_entry == NULL)       {	DEBUG(LOG_WARNING, 0,	      "rrep_ack_process: No RREP_ACK expected for %s",	      ip6_to_str(ip_src));	return;      }    DEBUG(LOG_DEBUG, 0, "rrep_ack_process: Received RREP_ACK from %s",	  ip6_to_str(ip_src));#else    if (rt_entry == NULL)       {	DEBUG(LOG_WARNING, 0,	      "rrep_ack_process: No RREP_ACK expected for %s",	      ip_to_str(ip_src));	return;      }    DEBUG(LOG_DEBUG, 0, "rrep_ack_process: Received RREP_ACK from %s",	  ip_to_str(ip_src));#endif /*IPV6 */    /* Remove unexpired timer for this RREP_ACK */    timer_remove(&rt_entry->ack_timer);}//PL:#ifdef _IPV6void NS_CLASS rrep_process(RREP * rrep, int rreplen, struct in6_addr ip_src,			   struct in6_addr ip_dst, int ip_ttl, 			   unsigned int ifindex)#elsevoid NS_CLASS rrep_process(RREP * rrep, int rreplen, u_int32_t ip_src,			   u_int32_t ip_dst, int ip_ttl, unsigned int ifindex)#endif /* _IPV6 */{    //PL:#ifdef _IPV6    struct in6_addr rrep_dest, rrep_orig;#else    u_int32_t rrep_dest, rrep_orig;#endif /* _IPV6 */    u_int32_t rrep_lifetime, rrep_seqno;    u_int8_t pre_repair_hcnt = 0;    rt_table_t *fwd_rt, *rev_rt,*fwd_default_rt=NULL;    dest_list_t *seek_dest_curr;    struct timeval lifetime;    char global_prefix[IP6ADDR_STR_LEN+3];    int to_me;    /* Convert to correct byte order on affeected fields: */    //PL:#ifdef _IPV6    copy_in6_addr(&rrep_dest, &rrep->dest_addr);    copy_in6_addr(&rrep_orig, &rrep->orig_addr);#else    rrep_dest = ntohl(rrep->dest_addr);    rrep_orig = ntohl(rrep->orig_addr);#endif /* _IPV6 */    rrep_seqno = ntohl(rrep->dest_seqno);    rrep_lifetime = ntohl(rrep->lifetime);	printf("ZJH:rrep_dest:%s rrep_orig:%s rrep_seqno:%d rrep_lifetime:%d\n",ip6_to_str(rrep_dest),ip6_to_str(rrep_orig),rrep_seqno,rrep_lifetime);    if (rreplen < (int) RREP_SIZE)       {	//PL:#ifdef _IPV6	log(LOG_WARNING, 0,	    "rrep_process: IP data field too short (%u bytes)"	    " from %s to %s", rreplen, ip6_to_str(ip_src), ip6_to_str(ip_dst));#else	log(LOG_WARNING, 0,	    "rrep_process: IP data field too short (%u bytes)"	    " from %s to %s", rreplen, ip_to_str(ip_src), ip_to_str(ip_dst));#endif /* _IPV6 */	return;      }    /* Ignore messages which aim to a create a route to one self */    //PL:#ifdef _IPV6    /*if ((memcmp(&rrep_dest, &DEV_IFINDEX(ifindex).ipaddr,	       sizeof(struct in6_addr)) == 0) &&	(memcmp(&rrep_orig, &DEV_IFINDEX(ifindex).ipaddr,		sizeof(struct in6_addr)) == 0) )*/    if(to_my_address(rrep_dest)&&to_my_address(rrep_orig))	return;    DEBUG(LOG_DEBUG, 0, "RREP_process: from %s about %s->%s",	  ip6_to_str(ip_src), ip6_to_str(rrep_orig), ip6_to_str(rrep_dest));#else    if (memcmp(&rrep_dest, &DEV_IFINDEX(ifindex).ipaddr,	       sizeof(u_int32_t)) == 0 &&	memcmp(&rrep_orig, &DEV_IFINDEX(ifindex).ipaddr,	       sizeof(u_int32_t)) == 0)	return;    DEBUG(LOG_DEBUG, 0, "RREP_process: from %s about %s->%s",	  ip_to_str(ip_src), ip_to_str(rrep_orig), ip_to_str(rrep_dest));#endif /* _IPV6 */#ifdef DEBUG_OUTPUT    log_pkt_fields((AODV_msg *) rrep);#endif    /* ---------- CHECK IF WE SHOULD MAKE A FORWARD ROUTE ------------ */    fwd_rt = rt_table_find(rrep_dest);    if (!fwd_rt) {	/* We didn't have an existing entry, so we insert a new one. */	fwd_rt = rt_table_insert(rrep_dest, ip_src, rrep->hcnt + 1, rrep_seqno,				 rrep_lifetime, FWD_ROUTE, ifindex);    } else if (rrep_seqno > fwd_rt->dest_seqno ||	       ((rrep_seqno == fwd_rt->dest_seqno &&	       (fwd_rt->hcnt == INFTY ||		rrep->hcnt < fwd_rt->hcnt || fwd_rt->flags & UNIDIR)))) {	pre_repair_hcnt = fwd_rt->last_hcnt;	fwd_rt = rt_table_update(fwd_rt, ip_src, rrep->hcnt + 1, rrep_seqno,				 rrep_lifetime, FWD_ROUTE);    } else {    	if(!(rrep->i)){		DEBUG(LOG_DEBUG, 0,	      		"rrep_process: Dropping RREP, fwd_rt->hcnt=%d fwd_rt->seqno=%ld",	      		fwd_rt->hcnt, fwd_rt->dest_seqno);		return;	}    }        if((rrep->i)&&internet_gw_mode){    	sprintf(global_prefix,"%s/%d",ip6_to_str(rrep->dest_addr),rrep->prefix);    	global_address_config(global_prefix);    	fwd_default_rt=rt_table_find(ipv6_dest_default);	/*if(fwd_default_rt)		rt_table_update(fwd_default_rt,rrep_dest,0,0,rrep_lifetime,FWD_ROUTE);	else		rt_table_insert(ipv6_dest_default,rrep_dest,0,0,rrep_lifetime,FWD_ROUTE,ifindex);	*/	if(fwd_default_rt)		rt_table_update(fwd_default_rt,ip_src,0,0,rrep_lifetime,FWD_ROUTE);	else		rt_table_insert(ipv6_dest_default,ip_src,0,0,rrep_lifetime,FWD_ROUTE,ifindex);	seek_dest_curr=seek_list_find_i();	to_me=to_my_address(rrep_orig);	while(seek_dest_curr){		fwd_default_rt=rt_table_find(seek_dest_curr->dest_addr);		if(fwd_default_rt)			rt_table_update(fwd_default_rt,ip_src,0,0,rrep_lifetime,FWD_ROUTE);		else			rt_table_insert(seek_dest_curr->dest_addr,ip_src,0,0,rrep_lifetime,FWD_ROUTE,ifindex);		if(to_me&&seek_list_remove(seek_dest_curr->dest_addr))			packet_queue_send(seek_dest_curr->dest_addr);		seek_dest_curr=seek_dest_curr->next;	}    }    /* Check if this RREP was for us (i.e. we previously made a RREQ       for this host). */    //PL:#ifdef _IPV6    //if (memcmp(&rrep_orig, &DEV_IFINDEX(ifindex).ipaddr,sizeof(struct in6_addr)) == 0)    if(to_my_address(rrep_orig))#else    if (memcmp(&rrep_orig, &DEV_IFINDEX(ifindex).ipaddr,	       sizeof(u_int32_t)) == 0)#endif /* _IPV6 */       {	/* Remove destination from seeking list since a route has been	   found. */	if (seek_list_remove(rrep_dest))	  packet_queue_send(rrep_dest);		/* If the RREP_ACK flag is set we must send a RREP	   acknowledgement to the destination that replied... */	if (rrep->a) 	  {	    RREP_ack *rrep_ack;	    	    rrep_ack = rrep_ack_create();	    aodv_socket_send((AODV_msg *) rrep_ack, fwd_rt->next_hop,			     NEXT_HOP_WAIT, MAXTTL,			     &DEV_IFINDEX(fwd_rt->ifindex));	    /* Remove RREP_ACK flag... */	    rrep->a = 0;	  }	if (fwd_rt->flags & LREPAIR) 	  {	    if (fwd_rt->hcnt > pre_repair_hcnt) 	      {		RERR *rerr;		u_int8_t rerr_flags = 0;		rerr_flags |= RERR_NODELETE;		rerr = rerr_create(rerr_flags, fwd_rt->dest_addr,				   fwd_rt->dest_seqno);		//PL:#ifdef _IPV6		aodv_socket_send((AODV_msg *) rerr, ipv6_multicast_addr,				 RERR_CALC_SIZE(rerr), 1,				 &DEV_IFINDEX(fwd_rt->ifindex));#else		aodv_socket_send((AODV_msg *) rerr, AODV_BROADCAST,				 RERR_CALC_SIZE(rerr), 1,				 &DEV_IFINDEX(fwd_rt->ifindex));#endif	      }	  }      }     else       {	/* --- Here we FORWARD the RREP on the REVERSE route --- */	/* If the current node is not the source node as indicated by the	   Source IP Address in the RREP message AND a forward route has	   been created or updated as described before, the node consults	   its route table entry for the source node to determine the next	   hop for the RREP packet, and then forwards the RREP towards the	   source with its Hop Count incremented by one. */	if((rrep->i)&&(internet_gw_mode==0))/*if disable gw_mode,don't forward GW_ADV*/		return;	rev_rt = rt_table_find_active(rrep_orig);	if (rev_rt) {	    /* Here we should do a check if we should request a RREP_ACK,	       i.e we suspect a unidirectional link.. But how? */	    if (0) {		rt_table_t *neighbor;		/* If the source of the RREP is not a neighbor we must find the		   neighbor (link) entry which is the next hop towards the RREP		   source... */		//PL:#ifdef _IPV6		if (memcmp(&rev_rt->dest_addr, &rev_rt->next_hop, sizeof(struct in6_addr)) != 0)#else		if (rev_rt->dest_addr != rev_rt->next_hop)#endif /* _IPV6 */		    neighbor = rt_table_find(rev_rt->next_hop);		else		    neighbor = rev_rt;		if (neighbor != NULL && !neighbor->ack_timer.used) {		    /* If the node we received a RREQ for is a neighbor we are		       probably facing a unidirectional link... Better request a		       RREP-ack */		    rrep->a = 1;		    neighbor->flags |= UNIDIR;		    timer_add_msec(&neighbor->ack_timer, NEXT_HOP_WAIT);		}	    }	    //PL:#ifdef _IPV6	    DEBUG(LOG_DEBUG, 0, "rrep_process: forwarding RREP to %s",		  ip6_to_str(rev_rt->next_hop));#else	    DEBUG(LOG_DEBUG, 0, "rrep_process: forwarding RREP to %s",		  ip_to_str(rev_rt->next_hop));#endif /* _IPV6 */	    rrep = (RREP *) aodv_socket_queue_msg((AODV_msg *) rrep, rreplen);	    rrep->hcnt = fwd_rt->hcnt;	/* Update the hopcount */	    aodv_socket_send((AODV_msg *) rrep, rev_rt->next_hop,			     RREP_SIZE, --ip_ttl,			     &DEV_IFINDEX(rev_rt->ifindex));	    /* The neighboring nodes to which a RREP was forwarded should be 	       added as a precursor node. */	    if (fwd_rt)		precursor_add(fwd_rt, rev_rt->next_hop);	    /* At each node the (reverse) route used to forward the	       RREP has its lifetime changed to the maximum of current	       time and current time plus ACTIVE_ROUTE_TIMEOUT. */	    gettimeofday(&lifetime, NULL);	    timeval_add_msec(&lifetime, ACTIVE_ROUTE_TIMEOUT);	    if (timeval_diff(&rev_rt->rt_timer.timeout, &lifetime) < 0)		rt_table_update_timeout(rev_rt, ACTIVE_ROUTE_TIMEOUT);	}#ifdef DEBUG	else	    DEBUG(LOG_DEBUG, 0,		  "rrep_process: Could not forward RREP - NO ROUTE!!!");#endif    }}/************************************************************************//* Include a Hello Interval Extension on the RREP return new offset */int rrep_add_hello_ext(RREP * rrep, int offset, u_int32_t interval){    AODV_ext *ext;    ext = (AODV_ext *) ((char *) rrep + RREP_SIZE + offset);    ext->type = RREP_HELLO_INTERVAL_EXT;    ext->length = sizeof(interval);    memcpy(AODV_EXT_DATA(ext), &interval, sizeof(interval));    return (offset + AODV_EXT_SIZE(ext));}

⌨️ 快捷键说明

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