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

📄 aodv_rreq.c

📁 支持IPv6的adov路由协议(本人修改后)
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************** * * Copyright (C) 2001 Uppsala University and 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_rreq.h"#include "aodv_rrep.h"#include "routing_table.h"#include "aodv_timeout.h"#include "k_route.h"#include "timer_queue.h"#include "aodv_socket.h"#include "params.h"#include "seek_list.h"#include "defs.h"#include "debug.h"#include "address_conf.h"//PL:#ifdef _IPV6#include "ipv6_utils.h"#endif /* _IPV6 */#endif /* NS_PORT */#ifndef NS_PORTstatic struct rreq_record *rreq_record_head = NULL;static struct blacklist *rreq_blacklist_head = NULL;//PL:#ifdef _IPV6static struct rreq_record *rreq_record_insert(struct in6_addr orig_addr,					      u_int32_t rreq_id);static struct rreq_record *rreq_record_find(struct in6_addr orig_addr,					    u_int32_t rreq_id);struct blacklist *rreq_blacklist_find(struct in6_addr dest_addr);#elsestatic struct rreq_record *rreq_record_insert(u_int32_t orig_addr,					      u_int32_t rreq_id);static struct rreq_record *rreq_record_find(u_int32_t orig_addr,					    u_int32_t rreq_id);struct blacklist *rreq_blacklist_find(u_int32_t dest_addr);#endif /* _IPV6 */extern int unidir_hack, rreq_gratuitous, expanding_ring_search;extern int internet_gw_mode,is_gateway;#endif//PL:#ifdef _IPV6RREQ *NS_CLASS rreq_create(u_int8_t flags, struct in6_addr dest_addr,			   u_int32_t dest_seqno, struct in6_addr orig_addr)#elseRREQ *NS_CLASS rreq_create(u_int8_t flags, u_int32_t dest_addr,			   u_int32_t dest_seqno, u_int32_t orig_addr)#endif /* _IPV6 */{    RREQ *rreq;    rreq = (RREQ *) aodv_socket_new_msg();    rreq->type = AODV_RREQ;    rreq->res1 = 0;    rreq->res2 = 0;    rreq->hcnt = 0;    rreq->rreq_id = htonl(this_host.rreq_id++);    rreq->dest_seqno = htonl(dest_seqno);    //PL:#ifdef _IPV6    copy_in6_addr(&rreq->dest_addr, &dest_addr);    copy_in6_addr(&rreq->orig_addr, &orig_addr);#else    rreq->dest_addr = htonl(dest_addr);    rreq->orig_addr = htonl(orig_addr);#endif /* _IPV6 */    /* Immediately before a node originates a RREQ flood it must       increment its sequence number... (AODV draft v.10, section 6.1). */    rreq->orig_seqno = htonl(++this_host.seqno);    if (flags & RREQ_INTERNET)        rreq->i = 1;    if (flags & RREQ_JOIN)	rreq->j = 1;    if (flags & RREQ_REPAIR)	rreq->r = 1;    if (flags & RREQ_GRATUITOUS)	rreq->g = 1;    //PL:#ifdef _IPV6    DEBUG(LOG_DEBUG, 0, "rreq_create: Assembled RREQ %s", ip6_to_str(dest_addr));#else    DEBUG(LOG_DEBUG, 0, "rreq_create: Assembled RREQ %s", ip_to_str(dest_addr));#endif /* _IPV6 */#ifdef DEBUG_OUTPUT    log_pkt_fields((AODV_msg *) rreq);#endif    return rreq;}//PL:#ifdef _IPV6void NS_CLASS rreq_process(RREQ * rreq, int rreqlen, struct in6_addr ip_src,			   struct in6_addr ip_dst, int ip_ttl, 			   unsigned int ifindex)#elsevoid NS_CLASS rreq_process(RREQ * rreq, int rreqlen, u_int32_t ip_src,			   u_int32_t ip_dst, int ip_ttl, unsigned int ifindex)#endif /* _IPV6 */{    AODV_ext *ext;    RREP *rrep;    rt_table_t *rev_rt, *fwd_rt = NULL/*,*fwd_gw_rt=NULL*/;    //PL:#ifdef _IPV6    struct in6_addr rreq_orig, rreq_dest;#else    u_int32_t rreq_orig, rreq_dest;#endif /* _IPV6 */    u_int32_t rreq_orig_seqno, rreq_dest_seqno;    u_int32_t rreq_id, life, lifetime;    u_int8_t flags = 0,prefix=0;    struct timeval minimal_lifetime, now;    rreq_id = ntohl(rreq->rreq_id);    //PL:#ifdef _IPV6    copy_in6_addr(&rreq_dest, &rreq->dest_addr);    copy_in6_addr(&rreq_orig, &rreq->orig_addr);#else    rreq_dest = ntohl(rreq->dest_addr);    rreq_orig = ntohl(rreq->orig_addr);#endif /* _IPV6 */    rreq_dest_seqno = ntohl(rreq->dest_seqno);    rreq_orig_seqno = ntohl(rreq->orig_seqno);    /* Ignore RREQ's that originated from this node. Either we do this       or we buffer our own sent RREQ's as we do with others we       receive. */    //PL:#ifdef _IPV6    //if (memcmp(&rreq_orig, &(DEV_IFINDEX(ifindex).ipaddr), sizeof(struct in6_addr)) ==0)    if(to_my_address(rreq_orig))	return;    if (rreqlen < (int) RREQ_SIZE) {	log(LOG_WARNING, 0,	    "rreq_process: IP data field too short (%u bytes)"	    "from %s to %s", rreqlen, ip6_to_str(ip_src), ip6_to_str(ip_dst));	return;    }    DEBUG(LOG_DEBUG, 0,	  "RREQ_process: ip_src=%s rreq_orig=%s rreq_dest=%s",	  ip6_to_str(ip_src), ip6_to_str(rreq_orig), ip6_to_str(rreq_dest));#else    if (rreq_orig == DEV_IFINDEX(ifindex).ipaddr)	return;    if (rreqlen < (int) RREQ_SIZE) {	log(LOG_WARNING, 0,	    "rreq_process: IP data field too short (%u bytes)"	    "from %s to %s", rreqlen, ip_to_str(ip_src), ip_to_str(ip_dst));	return;    }    DEBUG(LOG_DEBUG, 0,	  "RREQ_process: ip_src=%s rreq_orig=%s rreq_dest=%s",	  ip_to_str(ip_src), ip_to_str(rreq_orig), ip_to_str(rreq_dest));#endif /* _IPV6 */    /* Check if the previous hop of the RREQ is in the blacklist set. If       it is, then ignore the RREQ (AODV draft v.10, section 6.8). */    if (rreq_blacklist_find(ip_src)) {	DEBUG(LOG_DEBUG, 0,	      "rreq_process: prev hop of RREQ blacklisted, ignoring!");	return;    }    /* Ignore already processed RREQs. */    if (rreq_record_find(rreq_orig, rreq_id))	return;    /* Now buffer this RREQ so that we don't process a similar RREQ we       get within PATH_TRAVERSAL_TIME. */    rreq_record_insert(rreq_orig, rreq_id);    /* Determine whether there are any RREQ extensions */    ext = (AODV_ext *) ((char *) rreq + RREQ_SIZE);    while (rreqlen > (int) RREQ_SIZE) {	switch (ext->type) {	case RREQ_EXT:	    DEBUG(LOG_INFO, 0, "rreq_process: RREQ include EXTENSION");	    /* Do something here */	    break;	default:	    log(LOG_WARNING, 0, "rreq_process: Unknown extension type %d",		ext->type);	    break;	}	rreqlen -= AODV_EXT_SIZE(ext);	ext = AODV_EXT_NEXT(ext);    }#ifdef DEBUG_OUTPUT    log_pkt_fields((AODV_msg *) rreq);#endif    /* Check J and R flags: */    if (rreq->j) {	/* We don't have multicasting implemented... */    }    /* The node always creates or updates a REVERSE ROUTE entry to the       source of the RREQ. (AODV draft v.10, section 6.5). */    rev_rt = rt_table_find(rreq_orig);    /* Calculate the extended minimal life time as defined in section       6.5, draft 10. */    life = PATH_TRAVERSAL_TIME - 2 * (rreq->hcnt + 1) * NODE_TRAVERSAL_TIME;    if (rev_rt == NULL) {	DEBUG(LOG_DEBUG, 0, "rreq_process: rev_rt = NULL; route not found");	rev_rt = rt_table_insert(rreq_orig, ip_src, rreq->hcnt + 1,				 rreq_orig_seqno, life, REV_ROUTE, ifindex);    } else {	/* OK, existing entry found. But we update only if either:	   (i) the Originator Sequence Number in the RREQ is higher than	   the destination sequence number of the Originator IP Address	   in the route table, or	   (ii) the sequence numbers are equal, but the hop count as	   specified by the RREQ, plus one, is now smaller than the existing	   hop count in the routing table.	 */	if (((rreq_orig_seqno > rev_rt->dest_seqno) ||	     (rreq_orig_seqno == rev_rt->dest_seqno &&	      (rreq->hcnt + 1) < rev_rt->hcnt))) {	    gettimeofday(&minimal_lifetime, NULL);	    timeval_add_msec(&minimal_lifetime, life);	    /* If the expire time of the route is larger than the minimal	       lifetime, we don't do anything with the expire time,	       i.e. life = 0 */	    if (rev_rt->hcnt != INFTY &&		timeval_diff(&rev_rt->rt_timer.timeout, &minimal_lifetime) > 0)		life = 0;	    rev_rt = rt_table_update(rev_rt, ip_src, rreq->hcnt + 1,				     rreq_orig_seqno, life, REV_ROUTE);	}    }  /**** END updating/creating REVERSE route ****/    /* BAD HACK for Internet gateway support: */    //PL: Not sure what to do for now#ifdef _IPV6    //PL: We don't have netmask, comment this code for now    /*    if (internet_gw_mode &&	this_host.gateway_mode &&	(rreq_dest & DEV_IFINDEX(ifindex).netmask) !=	(DEV_IFINDEX(ifindex).ipaddr & DEV_IFINDEX(ifindex).netmask))      {	rrep = rrep_create(flags, 0, 0, rreq_dest, this_host.seqno,			   rreq_orig, MY_ROUTE_TIMEOUT);	aodv_socket_send((AODV_msg *) rrep, ip_src, RREP_SIZE, MAXTTL,			 &DEV_IFINDEX(ifindex));	return;      }    */#else    if (internet_gw_mode &&	this_host.gateway_mode &&	(rreq_dest & DEV_IFINDEX(ifindex).netmask) !=	(DEV_IFINDEX(ifindex).ipaddr & DEV_IFINDEX(ifindex).netmask))      {	rrep = rrep_create(flags, 0, 0, rreq_dest, this_host.seqno,			   rreq_orig, MY_ROUTE_TIMEOUT);	aodv_socket_send((AODV_msg *) rrep, ip_src, RREP_SIZE, MAXTTL,			 &DEV_IFINDEX(ifindex));	return;      }#endif /* _IPV6 */    /* Are we the destination of the RREQ?, if so we should immediately send a       RREP.. */    //PL:#ifdef _IPV6    //if ((memcmp(&rreq_dest, &DEV_IFINDEX(ifindex).ipaddr,sizeof(struct in6_addr)) == 0)||    if(to_my_address(rreq_dest)||	      ((rreq->i)&&is_gateway&&(memcmp(&rreq_dest,&DEV_IFINDEX(ifindex).gateway_mcast,sizeof(struct in6_addr))==0))) #else    if (memcmp(&rreq_dest, &DEV_IFINDEX(ifindex).ipaddr,	       sizeof(u_int32_t)) == 0) #endif /* _IPV6 */      {	/* WE are the RREQ DESTINATION.  (AODV draft v.10, section 6.6.1).	   Update the node's own sequence number to the maximum of the	   current seqno and the one in the RREQ. (Also section 6.1) */	if (this_host.seqno < rreq_dest_seqno)	    this_host.seqno = rreq_dest_seqno;	if ((rev_rt->hcnt != INFTY && rev_rt->flags & UNIDIR) ||	    ((rreq->hcnt + 1) == 1 && unidir_hack)) {	    rt_table_t *neighbor = rev_rt;	    /* If the source of the RREQ is not a neighbor we must find the	       neighbor (link) entry which is the next hop towards the RREQ	       source... */	    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 */		flags |= RREP_ACK;		neighbor->flags |= UNIDIR;		/* Must remove any pending hello timeouts when we set the		   UNIDIR flag, else the route may expire after we begin to		   ignore hellos... */		timer_remove(&neighbor->hello_timer);		timer_timeout_now(&neighbor->rt_timer);		//PL:#ifdef _IPV6		DEBUG(LOG_DEBUG, 0,		      "rreq_process: Link to %s is unidirectional!",		      ip6_to_str(neighbor->dest_addr));#else		DEBUG(LOG_DEBUG, 0,		      "rreq_process: Link to %s is unidirectional!",		      ip_to_str(neighbor->dest_addr));#endif /* _IPV6 */		timer_add_msec(&neighbor->ack_timer, NEXT_HOP_WAIT);	    }	}	if(rreq->i){		flags |=RREP_INTERNET;		prefix=new_ip6addr_head->next->plen; /*global address prefix length*/		if(new_ip6addr_head->next)			rreq_dest=new_ip6addr_head->next->ip6_in6addr;		else			return;			}	/* The destination node copies the value MY_ROUTE_TIMEOUT into the	   Lifetime field of the RREP. Each node MAY make a separate	   determination about its value MY_ROUTE_TIMEOUT.  */	rrep = rrep_create(flags,prefix, 0, rreq_dest,			   this_host.seqno, rreq_orig, MY_ROUTE_TIMEOUT);	aodv_socket_send((AODV_msg *) rrep, ip_src, RREP_SIZE, MAXTTL,			 &DEV_IFINDEX(rev_rt->ifindex));	return;      }    /* We are an INTERMEDIATE node.        - check if we have an active route entry */    if(rreq->i){    	fwd_rt=rt_table_find_active(ipv6_dest_default);	flags |=RREP_INTERNET;        if(fwd_rt){		rreq_dest=fwd_rt->dest_addr;		prefix=new_ip6addr_head->next->plen;		fwd_rt=rt_table_find_active(fwd_rt->next_hop);	}    }else    	fwd_rt = rt_table_find_active(rreq_dest);    if (fwd_rt && fwd_rt->dest_seqno >= rreq_dest_seqno) {	/* GENERATE RREP, i.e we have an ACTIVE route entry that is fresh	   enough (our destination sequence number for that route is	   larger than the one in the RREQ). */	gettimeofday(&now, NULL);	lifetime = timeval_diff(&fwd_rt->rt_timer.timeout, &now) / 1000;	rrep = rrep_create(flags, prefix, fwd_rt->hcnt, rreq_dest,				fwd_rt->dest_seqno, rreq_orig, lifetime);	aodv_socket_send((AODV_msg *) rrep, ip_src, RREP_SIZE, MAXTTL,			 &DEV_IFINDEX(ifindex));	/* Update precursor lists */	precursor_add(fwd_rt, ip_src);	precursor_add(rev_rt, fwd_rt->next_hop);	/* If the GRATUITOUS flag is set, we must also unicast a	   gratuitous RREP to the destination. */	if (rreq->g) {	    rrep = rrep_create(flags, 0, rev_rt->hcnt, rreq_orig,			       rreq_orig_seqno, rreq_dest, lifetime);	    aodv_socket_send((AODV_msg *) rrep, rreq_dest, RREP_SIZE,			     MAXTTL, &DEV_IFINDEX(fwd_rt->ifindex));	    //PL:#ifdef _IPV6	    DEBUG(LOG_INFO, 0,		  "rreq_process: Sending G-RREP to %s with rte to %s",

⌨️ 快捷键说明

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