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

📄 aodv_hello.c

📁 支持IPv6的adov路由协议(本人修改后)
💻 C
字号:
/***************************************************************************** * * 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_hello.h"#include "aodv_timeout.h"#include "aodv_rrep.h"#include "aodv_rreq.h"#include "routing_table.h"#include "packet_queue.h"#include "timer_queue.h"#include "params.h"#include "aodv_socket.h"#include "defs.h"#include "debug.h"#include "ipv6_utils.h"#include "address_conf.h"#endif/*ZJH*/ #define DEBUG_HELLO/*ZJH */#define ROUTE_TIMEOUT_SLACK 100#define JITTER_INTERVAL 100#ifndef NS_PORTextern int unidir_hack, receive_n_hellos, hello_jittering;static struct timer hello_timer;#endif//extern struct in6_addr gateway_mcast_addr;long NS_CLASS hello_jitter(){    if (hello_jittering) {#ifdef NS_PORT	return (long) (((float) Random::integer(RAND_MAX + 1) / RAND_MAX - 0.5)		       * JITTER_INTERVAL);#else	return (long) (((float) random() / RAND_MAX - 0.5) * JITTER_INTERVAL);#endif    } else	return 0;}void NS_CLASS hello_init(){    DEBUG(LOG_DEBUG, 0, "hello_init: Starting to send HELLOs!");    hello_timer.handler = &NS_CLASS hello_send;    hello_timer.data = NULL;    hello_timer.used = 0;    /* Set first broadcast time */    gettimeofday(&this_host.bcast_time, NULL);    timer_add_msec(&hello_timer, HELLO_INTERVAL + hello_jitter());}void NS_CLASS hello_send(void *arg){    RREP *rrep;    AODV_ext *ext = NULL;    u_int8_t flags = 0;    long time_diff, jitter;    struct timeval now;    rt_table_t *entry;    int msg_size = RREP_SIZE;    int i;    //PL: debug    //printf("hello_send is called.\n");   //printf("ZJH:hello_send is called!!!\n");    gettimeofday(&now, NULL);    time_diff = timeval_diff(&now, &this_host.bcast_time);    jitter = hello_jitter();    /* This check will ensure we don't send unnecessary hello msgs, in case       we have sent other bcast msgs within HELLO_INTERVAL */    if (time_diff >= HELLO_INTERVAL * 1000) {	for (i = 0; i < MAX_NR_INTERFACES; i++) {	    if (!DEV_NR(i).enabled)		continue;#ifdef DEBUG_HELLO	    //PL:#ifdef _IPV6	    DEBUG(LOG_DEBUG, 0, "SEND_BCAST: sending Hello to %s",		  ip6_to_str(ipv6_multicast_addr));#else	    DEBUG(LOG_DEBUG, 0, "SEND_BCAST: sending Hello to %s",		  ip_to_str(AODV_BROADCAST));#endif /* _IPV6 */#endif /* DEBUG_HELLO */	    rrep = rrep_create(flags, 0, 0, DEV_NR(i).ipaddr,			       this_host.seqno,			       DEV_NR(i).ipaddr,			       ALLOWED_HELLO_LOSS * HELLO_INTERVAL);	    /* Assemble a RREP extension which contain our neighbor set... */	    if (unidir_hack) {	      //PL:#ifdef _IPV6	        struct in6_addr neigh;#else		u_int32_t neigh;#endif		int i;		ext = (AODV_ext *) ((char *) rrep + RREP_SIZE);		ext->type = RREP_HELLO_NEIGHBOR_SET_EXT;		ext->length = 0;		for (i = 0; i < RT_TABLESIZE; i++) {		    entry = routing_table[i];		    while (entry != NULL) {			/* If an entry has an active hello timer, we assume			   that we are receiving hello messages from that			   node... */			if (entry->hello_timer.used) {#ifdef DEBUG_HELLO			  //PL:#ifdef _IPV6			    DEBUG(LOG_INFO, 0,				  "hello_send: Adding %s to hello neighbor set ext",				  ip6_to_str(entry->dest_addr));#else			    DEBUG(LOG_INFO, 0,				  "hello_send: Adding %s to hello neighbor set ext",				  ip_to_str(entry->dest_addr));#endif /* _IPV6 */#endif /* DEBUG_HELLO */			    //PL: Need to verify the length is 16 instead of 4#ifdef _IPV6			    copy_in6_addr(&neigh, &entry->dest_addr);			    memcpy(AODV_EXT_NEXT(ext), &neigh, 16);			    ext->length += 16;#else			    neigh = htonl(entry->dest_addr);			    memcpy(AODV_EXT_NEXT(ext), &neigh, 4);			    ext->length += 4;#endif /* _IPV6 */			}			entry = entry->next;		    }		}		if (ext->length)		    msg_size = RREP_SIZE + AODV_EXT_SIZE(ext);	    }	    //PL:#ifdef _IPV6	    //PL:debug	    //printf("hello_send did call aodv_socket_send\n");	    //printf("ZJH:hello_send did call aodv_socket_send\n");	    aodv_socket_send((AODV_msg *) rrep,ipv6_multicast_addr, msg_size,			     1, &DEV_NR(i));#else	    aodv_socket_send((AODV_msg *) rrep, AODV_BROADCAST, msg_size,			     1, &DEV_NR(i));#endif /* _IPV6 */	}	timer_add_msec(&hello_timer, HELLO_INTERVAL + jitter);    } else {	if (HELLO_INTERVAL - time_diff / 1000 + jitter < 0)	    timer_add_msec(&hello_timer, HELLO_INTERVAL - time_diff / 1000 -			   jitter);	else	    timer_add_msec(&hello_timer, HELLO_INTERVAL - time_diff / 1000 +			   jitter);    }}/* Process a hello message */void NS_CLASS hello_process(RREP * hello, int rreplen, unsigned int ifindex){    //PL:#ifdef _IPV6    struct in6_addr hello_dst;    u_int32_t hello_seqno;    struct in6_addr ext_neighbor;#else    u_int32_t hello_dst, hello_seqno;    u_int32_t ext_neighbor;#endif /* _IPV6 */    u_int32_t hello_interval = HELLO_INTERVAL;    rt_table_t *rt_entry;    AODV_ext *ext = NULL;    int i, hcnt, unidir_link = 1;    struct timeval now;    gettimeofday(&now, NULL);    //PL:#ifdef _IPV6    copy_in6_addr(&hello_dst, &hello->dest_addr);#else    hello_dst = ntohl(hello->dest_addr);#endif /* _IPV6 */    hello_seqno = ntohl(hello->dest_seqno);    /* Check for hello interval extension: */    ext = (AODV_ext *) ((char *) hello + RREP_SIZE);    while (rreplen > (int) RREP_SIZE) {	switch (ext->type) {	case RREP_HELLO_INTERVAL_EXT:	  //PL:#ifdef _IPV6	    if (ext->length == 16) {		memcpy(&hello_interval, AODV_EXT_DATA(ext), 16);		hello_interval = ntohl(hello_interval);#else	    if (ext->length == 4) {		memcpy(&hello_interval, AODV_EXT_DATA(ext), 4);		hello_interval = ntohl(hello_interval);#endif /* _IPV6 */#ifdef DEBUG_HELLO		DEBUG(LOG_INFO, 0,		      "HELLO_process: Hello extension interval=%lu!",		      hello_interval);#endif	    } else		log(LOG_WARNING, 0,		    "hello_process: Bad hello interval extension!");	    break;	case RREP_HELLO_NEIGHBOR_SET_EXT:#ifdef DEBUG_HELLO	    DEBUG(LOG_INFO, 0, "HELLO_process: RREP_HELLO_NEIGHBOR_SET_EXT");#endif	    //PL:#ifdef _IPV6	    for (i = 0; i < ext->length; i = i + 16) 	      {		copy_in6_addr(&ext_neighbor, (struct in6_addr *)				     ((char *) AODV_EXT_DATA(ext) + i));		//if (memcmp(&ext_neighbor, &DEV_IFINDEX(ifindex).ipaddr,sizeof(struct in6_addr)) == 0)		if(to_my_address(ext_neighbor))		  {		    unidir_link = 0;		  }	      }#else	    for (i = 0; i < ext->length; i = i + 4) {		ext_neighbor = ntohl(*(u_int32_t *)				     ((char *) AODV_EXT_DATA(ext) + i));		if (memcmp(&ext_neighbor, &DEV_IFINDEX(ifindex).ipaddr, 4)		    == 0)		    unidir_link = 0;	    }#endif /* _IPV6 */	    break;	default:	    log(LOG_WARNING, 0,		"hello_process: Bad extension!! type=%d, length=%d",		ext->type, ext->length);	    ext = NULL;	    break;	}	if (ext == NULL)	    break;	rreplen -= AODV_EXT_SIZE(ext);	ext = AODV_EXT_NEXT(ext);    }#ifdef DEBUG_HELLO#ifdef _IPV6    DEBUG(LOG_DEBUG, 0, "hello_process: rcvd HELLO from %s, seqno %lu",	  ip6_to_str(hello_dst), hello_seqno);#else    DEBUG(LOG_DEBUG, 0, "hello_process: rcvd HELLO from %s, seqno %lu",	  ip_to_str(hello_dst), hello_seqno);#endif /* _IPV6 */#endif /* DEBUG_HELLO */    /* This neighbor should only be valid after receiving 3       consecutive hello messages... */    if (receive_n_hellos)	hcnt = INFTY;    else	hcnt = 1;    if ((rt_entry = rt_table_find(hello_dst)) == NULL) {	/* No active or expired route in the routing table. So we add a	   new entry... */	if (unidir_hack && unidir_link) {	  //PL: debug	  //printf("hello_process 1 call rt_table_insert\n");	    rt_entry =		rt_table_insert(hello_dst, hello_dst, INFTY, hello_seqno,				ALLOWED_HELLO_LOSS * HELLO_INTERVAL +				ROUTE_TIMEOUT_SLACK, UNIDIR, ifindex);	    //PL:#ifdef _IPV6	    DEBUG(LOG_INFO, 0, "hello_process: %s new NEIGHBOR, link UNI-DIR",		  ip6_to_str(rt_entry->dest_addr));#else	    DEBUG(LOG_INFO, 0, "hello_process: %s new NEIGHBOR, link UNI-DIR",		  ip_to_str(rt_entry->dest_addr));#endif /* _IPV6 */	} else {	  //PL: debug	  //printf("hello_process 2 call rt_table_insert\n");	    rt_entry =		rt_table_insert(hello_dst, hello_dst, hcnt, hello_seqno,				ALLOWED_HELLO_LOSS * HELLO_INTERVAL +				ROUTE_TIMEOUT_SLACK, NEIGHBOR, ifindex);	    //PL:#ifdef _IPV6	    DEBUG(LOG_INFO, 0, "hello_process: %s new NEIGHBOR!",		  ip6_to_str(rt_entry->dest_addr));#else	    DEBUG(LOG_INFO, 0, "hello_process: %s new NEIGHBOR!",		  ip_to_str(rt_entry->dest_addr));#endif /* _IPV6 */	}	rt_entry->hello_cnt = 1;    } else {	if (unidir_hack &&	    unidir_link &&	    rt_entry->hcnt != INFTY &&	    rt_entry->hcnt > 1 && !(rt_entry->flags & NEIGHBOR)) {	    goto hello_update;	}	if (receive_n_hellos && rt_entry->hello_cnt < (receive_n_hellos - 1)) {	    if (timeval_diff(&now, &rt_entry->last_hello_time) / 1000 <		(long) (hello_interval + hello_interval / 2))		rt_entry->hello_cnt++;	    else		rt_entry->hello_cnt = 1;	    rt_entry->last_hello_time = now;	    return;	}	/* Update sequence numbers if the hello contained new info... */	if (unidir_hack && unidir_link)	    rt_table_update(rt_entry, hello_dst, 1, hello_seqno,			    ALLOWED_HELLO_LOSS * HELLO_INTERVAL +			    ROUTE_TIMEOUT_SLACK, UNIDIR);	else	    rt_table_update(rt_entry, hello_dst, 1, hello_seqno,			    ALLOWED_HELLO_LOSS * HELLO_INTERVAL +			    ROUTE_TIMEOUT_SLACK, NEIGHBOR);    }    /* In case we were performing a route discovery, stop it now       and send any puffered packets... */    if (seek_list_remove(hello_dst))	packet_queue_send(hello_dst);  hello_update:    hello_update_timeout(rt_entry, ALLOWED_HELLO_LOSS * hello_interval);    rt_entry->last_hello_time = now;    return;}/* Used to update neighbor when non-hello AODV message is received... *///PL:#ifdef _IPV6void NS_CLASS hello_process_non_hello(AODV_msg * aodv_msg, struct in6_addr source,				      unsigned int ifindex)#elsevoid NS_CLASS hello_process_non_hello(AODV_msg * aodv_msg, u_int32_t source,				      unsigned int ifindex)#endif /* _IPV6 */{    rt_table_t *rt_entry = NULL;    //PL:#ifdef _IPV6    struct in6_addr ip_addr;#else    u_int32_t ip_addr;#endif /* _IPV6 */    u_int32_t seqno = 0;    unsigned int lifetime;    struct timeval new_timeout;    gettimeofday(&new_timeout, NULL);    lifetime = ALLOWED_HELLO_LOSS * HELLO_INTERVAL + ROUTE_TIMEOUT_SLACK;    switch (aodv_msg->type) {    case AODV_RREQ:      //PL:#ifdef _IPV6	copy_in6_addr(&ip_addr, &(((RREQ *) aodv_msg)->orig_addr));	if (!(memcmp(&ip_addr, &source, sizeof(struct in6_addr))))	    seqno = ntohl(((RREQ *) aodv_msg)->orig_seqno);#else	ip_addr = ntohl(((RREQ *) aodv_msg)->orig_addr);	if (ip_addr == source)	    seqno = ntohl(((RREQ *) aodv_msg)->orig_seqno);#endif /* _IPV6 */	break;    case AODV_RREP:	/* If the neighbor initially sent this RREP, we use the	 * lifetime field to determine the lifetime of the route. */      //PL:#ifdef _IPV6	copy_in6_addr(&ip_addr, &(((RREP *) aodv_msg)->dest_addr));	if (!(memcmp(&ip_addr, &source, sizeof(struct in6_addr))))	    lifetime = ntohl(((RREP *) aodv_msg)->lifetime);#else	ip_addr = ntohl(((RREP *) aodv_msg)->dest_addr);	if (ip_addr == source)	    lifetime = ntohl(((RREP *) aodv_msg)->lifetime);#endif /* _IPV6 */	break;    case AODV_RERR:	break;    default:	break;    }    rt_entry = rt_table_find(source);    /* Check message type, and if we can retrieve a sequence number */    if (rt_entry == NULL) {      //PL:#ifdef _IPV6	DEBUG(LOG_DEBUG, 0, "hello_process_non_hello: %s new NEIGHBOR!",	      ip6_to_str(source));#else	DEBUG(LOG_DEBUG, 0, "hello_process_non_hello: %s new NEIGHBOR!",	      ip_to_str(source));#endif /* _IPV6 */	//PL: debug	//printf("hello_process_non_hello called rt_table_insert\n");	rt_entry = rt_table_insert(source, source, 1, seqno,				   lifetime, NEIGHBOR, ifindex);    } else {	/* Don't update anything if this is a uni-directional link... */	if (rt_entry->flags & UNIDIR)	    return;	if (rt_entry->dest_seqno > seqno)	    seqno = rt_entry->dest_seqno;	timeval_add_msec(&new_timeout, lifetime);	if (timeval_diff(&rt_entry->rt_timer.timeout, &new_timeout) > 0)	    lifetime = 0;	rt_table_update(rt_entry, source, 1, seqno, lifetime, NEIGHBOR);    }    /* Remove destination from seeking list if a route has been       found and send any pending data packets. */    if (seek_list_remove(source))	packet_queue_send(source);#ifndef AODVUU_LL_FEEDBACK    hello_update_timeout(rt_entry, ALLOWED_HELLO_LOSS * HELLO_INTERVAL);#endif}#define HELLO_DELAY 50		/* The extra time we should allow an hello				   message to take (due to processing) before				   assuming lost . */inline void NS_CLASS hello_update_timeout(rt_table_t * rt_entry, long time){    timer_add_msec(&rt_entry->hello_timer, time + HELLO_DELAY);}

⌨️ 快捷键说明

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