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

📄 aodv_socket.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> * *****************************************************************************//* Uncomment if SOCK_RAW is to be used instead of SOCK_DGRAM.   SOCK_RAW code is not finished though... *//*  #define RAW_SOCKET   */#include <sys/types.h>#ifdef NS_PORT#include "aodv-uu.h"#else#include <sys/socket.h>#include <netinet/in.h>#include <net/if.h>#ifdef RAW_SOCKET#include <netinet/udp.h>#endif				/* RAW_SOCKET */#include "aodv_socket.h"#include "timer_queue.h"#include "aodv_rreq.h"#include "aodv_rerr.h"#include "aodv_rrep.h"#include "aodv_hello.h"#include "debug.h"#include "defs.h"#include "ipv6_utils.h"#include "address_areq.h"#include "address_arep.h"#endif				/* NS_PORT */#ifndef NS_PORT#define SO_RECVBUF_SIZE 256*1024//PL:#ifndef _IPV6static char recv_buf[RECV_BUF_SIZE];#endif /* _IPV6 */static char send_buf[SEND_BUF_SIZE];extern int wait_on_reboot, hello_qual_threshold;static void aodv_socket_read(int fd);/* For some reason, this struct is not picked up from any header file * when compiling against ARM... Therefore it must be defined here. */#ifdef ARMstruct in_pktinfo {    int ipi_ifindex;    struct in_addr ipi_spec_dst;    struct in_addr ipi_addr;};#endif				/* ARM */#endif				/* NS_PORT */void NS_CLASS aodv_socket_init(){#ifndef NS_PORT //PL:#ifdef _IPV6    struct sockaddr_in6 aodv_addr;#else    struct sockaddr_in aodv_addr;#endif /* _IPV6 */    struct ifreq ifr;    int i, retval = 0;    int on = 1;    int tos = IPTOS_LOWDELAY;    int bufsize = SO_RECVBUF_SIZE;    //PL: for IPv6 Multicast    struct ipv6_mreq mreq6;    int if_index;	printf("aodv socket init...\n");    /* Create a UDP socket */    if (this_host.nif == 0) {	fprintf(stderr, "aodv_socket_init: No interfaces configured\n");	exit(-1);    }    /* Open a socket for every AODV enabled interface */    for (i = 0; i < MAX_NR_INTERFACES; i++) {	if (!DEV_NR(i).enabled)	    continue;#ifdef RAW_SOCKET	DEV_NR(i).sock = socket(PF_INET, SOCK_RAW, IPPROTO_UDP);#else//PL:#ifdef _IPV6	DEV_NR(i).sock = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP);#else	DEV_NR(i).sock = socket(PF_INET, SOCK_DGRAM, 0);#endif /* _IPV6 */#endif /* RAW_SOCKET */	if (DEV_NR(i).sock < 0) {	    perror("aodv_socket_init: ");	    exit(-1);	}	/* Bind the socket to the AODV port number */	memset(&aodv_addr, 0, sizeof(aodv_addr));	//PL:#ifdef _IPV6	aodv_addr.sin6_family = AF_INET6;	aodv_addr.sin6_port = htons(AODV_PORT);	aodv_addr.sin6_addr = in6addr_any; //Doesn't need to do htonl, all 0#else	aodv_addr.sin_family = AF_INET;	aodv_addr.sin_port = htons(AODV_PORT);	aodv_addr.sin_addr.s_addr = htonl(INADDR_ANY);#endif /* _IPV6 */	//PL: Change the sizeof(struct sockaddr) to sizeof(aodv_addr)	/*	retval = bind(DEV_NR(i).sock, (struct sockaddr *) &aodv_addr,		      sizeof(struct sockaddr));	*/	retval = bind(DEV_NR(i).sock, (struct sockaddr *) &aodv_addr,		      sizeof(aodv_addr));	if (retval < 0) {	    perror("aodv_socket_init: Bind failed ");	    exit(-1);	}	//PL: IPv6 doesn't have broadcast#ifdef _IPV6	memcpy(&mreq6.ipv6mr_multiaddr, &(DEV_NR(i).multicast), 	       sizeof(struct in6_addr));	//copy_in6_addr(&mreq6.ipv6mr_multiaddr, &(DEV_NR(i).multicast));	mreq6.ipv6mr_interface = DEV_NR(i).ifindex;	if_index = DEV_NR(i).ifindex;	//PL: debug - For testing purpose	/*	printf("DEV_NR(%d).ifindex = %d\nMulticast Address = ", i, if_index);	print_ipv6_addr(DEV_NR(i).multicast);	printf("DEV_NR(%d).name = %s\n", i, DEV_NR(i).ifname);	*/	if(setsockopt(DEV_NR(i).sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, 		      &mreq6, sizeof(mreq6))<0)	  {	    fprintf(stderr,		    "aodv_socket_init: IPV6_ADD_MEMBERSHIP failed for %s",		    DEV_NR(i).ifname);	    perror(" ");	    exit(-1);	  }    	if(setsockopt(DEV_NR(i).sock, IPPROTO_IPV6, IPV6_MULTICAST_IF, 		      &if_index, sizeof(if_index))<0)	  {	    fprintf(stderr,		    "aodv_socket_init: IPV6_MULTICAST_IF failed for %s",		    DEV_NR(i).ifname);	    perror(" ");	    exit(-1);	  }#else	if (setsockopt(DEV_NR(i).sock, SOL_SOCKET, SO_BROADCAST,		       &on, sizeof(int)) < 0) {	    perror("aodv_socket_init: SO_BROADCAST failed ");	    exit(-1);	}#endif /* _IPV6 */	memset(&ifr, 0, sizeof(struct ifreq));	strcpy(ifr.ifr_name, DEV_NR(i).ifname);	//PL: This might still the same for IPv6	if (setsockopt(DEV_NR(i).sock, SOL_SOCKET, SO_BINDTODEVICE,		       &ifr, sizeof(ifr)) < 0) {	    fprintf(stderr,		    "aodv_socket_init: SO_BINDTODEVICE failed for %s",		    DEV_NR(i).ifname);	    perror(" ");	    exit(-1);	}	if (setsockopt(DEV_NR(i).sock, SOL_SOCKET, SO_PRIORITY,		       &tos, sizeof(int)) < 0) {	    perror("aodv_socket_init: Setsockopt SO_PRIORITY failed ");	    exit(-1);	}#ifdef RAW_SOCKET	/* We provide our own IP header... */	if (setsockopt(DEV_NR(i).sock, SOL_IP, IP_HDRINCL,		       &on, sizeof(int)) < 0) {	    perror("aodv_socket_init: Setsockopt IP_HDRINCL failed ");	    exit(-1);	}#else	#ifdef _IPV6	if (setsockopt(DEV_NR(i).sock, IPPROTO_IPV6, IPV6_PKTINFO,		       &on, sizeof(int)) < 0) {	    perror("aodv_socket_init: Setsockopt IPV6_PKTINFO failed ");	    exit(-1);	}	//PL: IPv6 has HOP_LIMIT instead of TTL	if (setsockopt(DEV_NR(i).sock, IPPROTO_IPV6, IPV6_HOPLIMIT,		       &on, sizeof(int)) < 0) {	    perror("aodv_socket_init: Setsockopt IPV6_HOPLIMIT failed ");	    exit(-1);	}#else	if (setsockopt(DEV_NR(i).sock, SOL_IP, IP_PKTINFO,		       &on, sizeof(int)) < 0) {	    perror("aodv_socket_init: Setsockopt IP_PKTINFO failed ");	    exit(-1);	}	if (setsockopt(DEV_NR(i).sock, SOL_IP, IP_RECVTTL,		       &on, sizeof(int)) < 0) {	    perror("aodv_socket_init: Setsockopt IP_TTL failed ");	    exit(-1);	}#endif /* _IPV6 */#endif /* RAW_SOCKET */	/* Set max allowable receive buffer size... */	for (;; bufsize -= 1024) {	    if (setsockopt(DEV_NR(i).sock, SOL_SOCKET, SO_RCVBUF,			   (char *) &bufsize, sizeof(bufsize)) == 0) {		log(LOG_NOTICE, 0,		    "aodv_socket_init: Receive buffer size set to %d", bufsize);		break;	    }	    if (bufsize < RECV_BUF_SIZE) {		log(LOG_ERR, 0,		    "aodv_socket_init: Could not set receive buffer size");		exit(-1);	    }	}	retval = attach_callback_func(DEV_NR(i).sock, aodv_socket_read);	if (retval < 0) {	    perror("aodv_socket_init: register input handler failed ");	    exit(-1);	}    }#endif				/* NS_PORT */}//PL:#ifdef _IPV6/* PL: Note that ttl change to hop_limit */void NS_CLASS aodv_socket_process_packet(AODV_msg * aodv_msg, int len, 					 struct in6_addr src, 					 struct in6_addr dst, 					 int hop_limit, unsigned int ifindex)#elsevoid NS_CLASS aodv_socket_process_packet(AODV_msg * aodv_msg, int len,					 u_int32_t src, u_int32_t dst,					 int ttl, unsigned int ifindex)#endif /* _IPV6 */{    /* Check if this was a HELLO message... */  //PL:#ifdef _IPV6    if ((aodv_msg->type == AODV_RREP && hop_limit == 1 && 	 !(memcmp(&dst, &ipv6_multicast_addr, sizeof(struct in6_addr))))){	hello_process((RREP *) aodv_msg, len, ifindex);	return;    }#else    if ((aodv_msg->type == AODV_RREP && ttl == 1 && dst == AODV_BROADCAST)) {	hello_process((RREP *) aodv_msg, len, ifindex);	return;    }#endif /* _IPV6 */    /* Treat this non-hello message as a HELLO so that neighbors are     * added to the routing table */    hello_process_non_hello(aodv_msg, src, ifindex);    /* Check what type of msg we received and call the corresponding       function to handle the msg... */    switch (aodv_msg->type)       {    case AODV_RREQ:	printf("ZJH:aodv_socket_process_packet:aodv rreq\n");#ifdef _IPV6	rreq_process((RREQ *) aodv_msg, len, src, dst, hop_limit, ifindex);#else	rreq_process((RREQ *) aodv_msg, len, src, dst, ttl, ifindex);#endif /*_IPV6 */	break;    case AODV_RREP:	printf("ZJH:aodv_socket_process_packet:aodv rrep\n");#ifdef _IPV6	rrep_process((RREP *) aodv_msg, len, src, dst, hop_limit, ifindex);#else	rrep_process((RREP *) aodv_msg, len, src, dst, ttl, ifindex);#endif /*_IPV6 */	break;    case AODV_RERR:	printf("ZJH:aodv_socket_process_packet:aodv rerr\n");	rerr_process((RERR *) aodv_msg, len, src, dst);	break;    case AODV_RREP_ACK:	printf("ZJH:aodv_socket_process_packet:aodv rrep_ack\n");	rrep_ack_process((RREP_ack *) aodv_msg, len, src, dst);	break;	case AODV_AREQ:		printf("aodv_socket_process_packet:aodv areq\n");		areq_process((AREQ *)aodv_msg,len,src,dst,hop_limit,ifindex);		break;	case AODV_AREP:		printf("aodv_socket_process_packet:aodv arep\n");		arep_process((AREP *)aodv_msg,len,src,dst,hop_limit,ifindex);		break;    default:#ifdef _IPV6	log(LOG_WARNING, 0,	    "aodv_socket_read: Unknown msg type %u rcvd from %s to %s",	    aodv_msg->type, ip6_to_str(src), ip6_to_str(dst));#else	log(LOG_WARNING, 0,	    "aodv_socket_read: Unknown msg type %u rcvd from %s to %s",	    aodv_msg->type, ip_to_str(src), ip_to_str(dst));#endif /* _IPV6 */      }}#ifdef NS_PORTvoid NS_CLASS recvAODVUUPacket(Packet * p){    int len, i, ttl = 0;    u_int32_t src, dst;    struct hdr_cmn *ch = HDR_CMN(p);    struct hdr_ip *ih = HDR_IP(p);    hdr_aodvuu *ah = HDR_AODVUU(p);    src = ih->saddr();    dst = ih->daddr();    len = ch->size() - IP_HDR_LEN;    ttl = ih->ttl();    AODV_msg *aodv_msg = (AODV_msg *) recv_buf;    /* Only handle AODVUU packets */    assert(ch->ptype() == PT_AODVUU);    /* Only process incoming packets */    assert(ch->direction() == hdr_cmn::UP);    /* Copy message to receive buffer */    memcpy(recv_buf, ah, RECV_BUF_SIZE);    /* Drop or deallocate packet, depending on the TTL */    /*   if (ttl == 1) *//* 	drop(p, DROP_RTR_TTL); *//*     else */    Packet::free(p);    /* Ignore messages generated locally */    for (i = 0; i < MAX_NR_INTERFACES; i++)	if (this_host.devs[i].enabled &&	    memcmp(&src, &this_host.devs[i].ipaddr, sizeof(u_int32_t)) == 0)	    return;    aodv_socket_process_packet(aodv_msg, len, src, dst, ttl, NS_IFINDEX);}#elsestatic void aodv_socket_read(int fd){  //PL:#ifdef _IPV6    struct in6_addr src, dst;    int i, len, hop_limit = 0, moveon = 0;    //PL: debug    /*//ZJH*/u_int8_t *debug_msg;#else    u_int32_t src, dst;    int i, len, ttl = 0;#endif /* _IPV6 */    AODV_msg *aodv_msg;#ifdef RAW_SOCKET    int iph_len;    struct iphdr *iph;    struct udphdr *udph;    len = recvfrom(fd, recv_buf, RECV_BUF_SIZE, 0, NULL, NULL);    if (len < 0 || len < IPHDR_SIZE) {	log(LOG_WARNING, 0, "aodv_socket_read: receive ERROR!");	return;    }    /* Parse the IP header */    iph = (struct iphdr *) recv_buf;    src = ntohl(iph->saddr);    dst = ntohl(iph->daddr);    ttl = iph->ttl;    iph_len = iph->ihl << 2;    udph = (struct udphdr *) (recv_buf + iph_len);    if (ntohs(udph->dest) != AODV_PORT && ntohs(udph->source) != AODV_PORT)	return;    /* Ignore messages generated locally */    for (i = 0; i < MAX_NR_INTERFACES; i++)	if (this_host.devs[i].enabled &&	    memcmp(&src, &this_host.devs[i].ipaddr, sizeof(u_int32_t)) == 0)	    return;    aodv_msg = (AODV_msg *) (recv_buf + iph_len + sizeof(struct udphdr));    len = ntohs(udph->len) - sizeof(struct udphdr);#else    //PL:#ifdef _IPV6    struct sockaddr_in6 src_addr;    //PL: Change to use recvmsg    unsigned char buffer[IP_MAXPACKET];    unsigned char msgbuffer[1024];    struct iovec iov = { (void *)&buffer, IP_MAXPACKET };    struct sockaddr_in6 addr;    struct msghdr msg = {      (void *)&addr, sizeof(addr),      &iov, 1,       (void *)&msgbuffer, sizeof(msgbuffer),       0    };    struct cmsghdr *cmsg;    struct in6_pktinfo pktinfo;#else    struct sockaddr_in src_addr;    struct msghdr msg;    union {	struct cmsghdr cm;	char control[CMSG_SPACE(sizeof(int)) +		     CMSG_SPACE(sizeof(struct in_pktinfo))];    } control_union;    struct cmsghdr *cmsg;    struct in_pktinfo pktinfo;    int sockaddr_len = sizeof(struct sockaddr_in);    msg.msg_name = NULL;    msg.msg_namelen = 0;    msg.msg_iov = NULL;    msg.msg_iovlen = 0;

⌨️ 快捷键说明

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