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

📄 aodv_socket.c

📁 支持IPv6的adov路由协议(本人修改后)
💻 C
📖 第 1 页 / 共 2 页
字号:
    msg.msg_control = control_union.control;    msg.msg_controllen = sizeof(control_union.control);#endif /* _IPV6 */    //PL: debug    //printf("aodv_socket_read is called\n");    /* Get the information control message first */    if ((len = recvmsg(fd, &msg, 0)) < 0) {	log(LOG_WARNING, 0, "aodv_socket_read: recvmsg ERROR!");	return;    }    //PL: debug    //printf("control message length = %d\n", len);    //PL: aodv message is in msg.msg_iov->iov_base    /* Read the data payload (i.e. AODV msg) */    /*    len = recvfrom(fd, recv_buf, RECV_BUF_SIZE, 0,		   (struct sockaddr *) &src_addr, &sockaddr_len);    if (len < 0) {	log(LOG_WARNING, 0, "aodv_socket_read: receive ERROR!");	return;    }    aodv_msg = (AODV_msg *) (recv_buf);    */    memcpy(&src_addr, msg.msg_name, 	   sizeof(struct sockaddr_in6));    aodv_msg = (AODV_msg *) msg.msg_iov->iov_base;    //PL: use IPv6 ntoh#ifdef _IPV6    copy_in6_addr(&src, &src_addr.sin6_addr);	printf("ZJH:aodv_socket_read called,source addr:%s\n",ip6_to_str(src));#else    src = ntohl(src_addr.sin_addr.s_addr);#endif /* _IPV6 */    /* Ignore messages generated locally */    for (i = 0; i < MAX_NR_INTERFACES; i++)      //PL:#ifdef _IPV6	if (this_host.devs[i].enabled &&	    memcmp(&src, &this_host.devs[i].ipaddr, 		   sizeof(struct in6_addr)) == 0)#else	if (this_host.devs[i].enabled &&	    memcmp(&src, &this_host.devs[i].ipaddr, sizeof(u_int32_t)) == 0)#endif /* _IPV6 */	  {	    //PL: debug	    //printf("This is local generated message\n");		printf("ZJH:This is local generated message!!!\n");	    return;	  }    //PL: debug - print aodv_message    /*ZJH*/	printf("ZJH:This is received message!!!\n");    debug_msg = (char *) (msg.msg_iov->iov_base);    printf("aodv_msg length = %d\naodv_msg =\n%2.2x ", len, debug_msg[0]);    for(i = 1 ; i < len; i ++)      {	printf("%2.2x ", debug_msg[i]);	if(!((i+1)%10))	  printf("\n");      }    printf("\n");    /*ZJH*/    //PL:#ifdef _IPV6    //PL: Need to verify CMSG_NXTHDR work as it mention in the original    //    doesn't work across different RedHat Linux        for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg))      {	//PL: debug	//printf("cmsg->cmsg_type =  %d\n", cmsg->cmsg_type);	if (cmsg->cmsg_type == IPV6_HOPLIMIT) 	  {	    hop_limit = (int) *CMSG_DATA(cmsg);	    //PL: Not sure why they do it this way	    //hopptr = (int *) CMSG_DATA(cmsg);	    //hops = *hopptr;	    	    //PL: debug	    //printf("cmsg_type = IPV6_HOPLIMIT, hop_limit = %d\n", hop_limit);		printf("ZJH:cmsg_type = IPV6_HOPLIMIT, hop_limit = %d\n", hop_limit);	    	  }	if (cmsg->cmsg_type == IPV6_PKTINFO) 	  {	    memcpy(&pktinfo, CMSG_DATA(cmsg), sizeof(pktinfo));	    //PL: Don't need to copy out	    //&pktinfo = (struct in6_pktinfo *) CMSG_DATA(cmsg);	    //memcpy(&daddr, &pktinfo.ipi6_addr, sizeof(struct in6_addr));	    //ifindex = pktinfo.ipi6_ifindex;	    	    //PL: debug	    /*	    printf("cmsg_type = IPV6_PKTINFO, pktinfo.ipi6_ifindex = %d\n", 		   pktinfo.ipi6_ifindex);	    */		printf("ZJH:cmsg_type = IPV6_PKTINFO, pktinfo.ipi6_ifindex = %d\n", 		   pktinfo.ipi6_ifindex);	    moveon = 1;	  }      }    copy_in6_addr(&dst, &pktinfo.ipi6_addr);    //PL: debug    //printf("aodv_socket_read: dst = %s\n", ip6_to_str(dst));	printf("ZJH:dst = %s!!!\n", ip6_to_str(dst));#else    /* Get the TTL and pktinfo struct (destination address) from the       control messages... For some reason the correct use of the       CMSG(3) macros using CMSG_NXTHDR does not work across different       Red Hat versions (6.2 vs 7.2), but this code seem to work: */    cmsg = CMSG_FIRSTHDR(&msg);    for (i = 0; i < 2; i++) {	if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_TTL) {	    memcpy(&ttl, CMSG_DATA(cmsg), sizeof(int));	    cmsg = (void *) cmsg + CMSG_SPACE(sizeof(int));	} else if (cmsg->cmsg_level == SOL_IP && 		   cmsg->cmsg_type == IP_PKTINFO) {	    memcpy(&pktinfo, CMSG_DATA(cmsg), sizeof(struct in_pktinfo));	    cmsg = (void *) cmsg + CMSG_SPACE(sizeof(struct in_pktinfo));	}    }    dst = ntohl(pktinfo.ipi_addr.s_addr);#endif /* _IPV6 */#endif /* RAW_SOCKET *///PL:#ifdef _IPV6    if(moveon)      {	//PL: debug	/*	printf("aodv_socket_read: pktinfo.ipi6_ifindex = %d\n", pktinfo.ipi6_ifindex);	*/	aodv_socket_process_packet(aodv_msg, len, src, dst, hop_limit,				   pktinfo.ipi6_ifindex);      }    else      {	printf("cannot retrieve cmsg correct,");	printf("will not proceed with aodv_socket_process_packet.\n");      }#else    aodv_socket_process_packet(aodv_msg, len, src, dst, ttl,			       pktinfo.ipi_ifindex);#endif /* _IPV6 */}#endif				/* NS_PORT *///PL:#ifdef _IPV6void aodv_socket_send(AODV_msg * aodv_msg, struct in6_addr dst, int len,		      u_int8_t hop_limit, struct dev_info *dev)#elsevoid NS_CLASS aodv_socket_send(AODV_msg * aodv_msg, u_int32_t dst, int len,			       u_int8_t ttl, struct dev_info *dev)#endif /* _IPV6 */{    int retval = 0;#ifndef NS_PORT    //PL:#ifdef _IPV6    struct sockaddr_in6 dst_addr;    int hop_limit_send;    struct iovec iov[1];    struct msghdr msg;    struct cmsghdr *cmsg;    int cmsglen;    struct in6_pktinfo pinfo;#else    struct sockaddr_in dst_addr;#endif /* _IPV6 */#ifdef RAW_SOCKET    struct iphdr *iph;    struct udphdr *udph;    if (wait_on_reboot && aodv_msg->type == AODV_RREP)	return;    /* Create a IP header around the packet... The AODV msg is already       located in the send buffer and referenced by the in parameter       "aodv_msg". */    iph = (struct iphdr *) send_buf;    iph->tot_len = htons(IPHDR_SIZE + sizeof(struct udphdr) + len);    iph->saddr = htonl(dev->ipaddr);    iph->daddr = htonl(dst);    iph->ttl = ttl;    udph = (struct udphdr *) (send_buf + IPHDR_SIZE);    udph->len = htons(len + sizeof(struct udphdr));#else /* Not RAW_SOCKET */    //PL: debug    //printf("aodv_socket_send is called\n");    /* If we are in waiting phase after reboot, don't send any RREPs */    if (wait_on_reboot && aodv_msg->type == AODV_RREP)	return;    //PL:#ifdef _IPV6    //PL: I guess is IPV6_UNICAST_HOPS, instead of IPV6_MULTICAST_HOPS    //PL: I think we might need to check if the address is for multicast over here    //PL: For some reason, setsockopt doesn't like to take u_int8_t    hop_limit_send = hop_limit;    if (setsockopt(dev->sock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,		   (char *) &hop_limit_send, sizeof(hop_limit_send)) == -1)      {	perror("setsockopt IPV6_MULTICAST_HOPS");	return;      }    //PL: Just set the hop limit, doesn't care it is unicast or not    if (setsockopt(dev->sock, IPPROTO_IPV6, IPV6_UNICAST_HOPS,		   (char *) &hop_limit_send, sizeof(hop_limit_send)) == -1)      {	perror("setsockopt IPV6_UNICAST_HOPS");	return;      }#else    /* Set the ttl we want to send with */    if (setsockopt(dev->sock, SOL_IP, IP_TTL, &ttl, sizeof(ttl)) < 0) {	log(LOG_WARNING, 0, "aodv_socket_send: Failed to set TTL!!!");	return;    }#endif /* _IPV6 */#endif /* RAW_SOCKET */    memset(&dst_addr, 0, sizeof(dst_addr));    //PL:#ifdef _IPV6    dst_addr.sin6_family = AF_INET6;    copy_in6_addr(&dst_addr.sin6_addr, &dst);    dst_addr.sin6_port = htons(AODV_PORT);#else    dst_addr.sin_family = AF_INET;    dst_addr.sin_addr.s_addr = htonl(dst);    dst_addr.sin_port = htons(AODV_PORT);#endif /* _IPV6 */#else  /* if define NS_PORT */    /*       NS_PORT: Sending of AODV_msg messages to other AODV-UU routing agents       by encapsulating them in a Packet.       Note: This method is _only_ for sending AODV packets to other routing       agents, _not_ for forwarding "regular" IP packets!     */    /* If we are in waiting phase after reboot, don't send any RREPs */    if (wait_on_reboot && aodv_msg->type == AODV_RREP)	return;    /*       NS_PORT: Don't allocate packet until now. Otherwise packet uid       (unique ID) space is unnecessarily exhausted at the beginning of       the simulation, resulting in uid:s starting at values greater than 0.     */    Packet *p = allocpkt();    struct hdr_cmn *ch = HDR_CMN(p);    struct hdr_ip *ih = HDR_IP(p);    hdr_aodvuu *ah = HDR_AODVUU(p);    // Clear AODVUU part of packet    memset(ah, '\0', ah->size());    // Copy message contents into packet    memcpy(ah, aodv_msg, len);    // Set common header fields    ch->ptype() = PT_AODVUU;    ch->direction() = hdr_cmn::DOWN;    ch->size() = IP_HDR_LEN + len;    ch->iface() = -2;    ch->error() = 0;    ch->prev_hop_ = (nsaddr_t) dev->ipaddr;    // Set IP header fields    ih->saddr() = (nsaddr_t) dev->ipaddr;    ih->daddr() = (nsaddr_t) dst;    ih->ttl() = ttl;    // Note: Port number for routing agents, not AODV port number!    ih->sport() = RT_PORT;    ih->dport() = RT_PORT;    // Fake success    retval = len;#endif				/* NS_PORT */    //PL: use sendmsg instead of sendto    memset(&pinfo, 0, sizeof(pinfo));    memcpy(&pinfo.ipi6_addr, &dev->ipaddr, sizeof(struct in6_addr));    //PL: I dpn't think we need to specify the ipi6_ifindex    /*    pinfo.ipi6_ifindex = dev->ifindex;    */    cmsglen = CMSG_SPACE(sizeof(pinfo));    cmsg = malloc(cmsglen);    if (cmsg == NULL) {      perror(__FUNCTION__);      return;    }    cmsg->cmsg_len = CMSG_LEN(sizeof(pinfo));    cmsg->cmsg_level = IPPROTO_IPV6;    cmsg->cmsg_type = IPV6_PKTINFO;    memcpy(CMSG_DATA(cmsg), &pinfo, sizeof(pinfo));    iov[0].iov_base = (unsigned char *)aodv_msg;    iov[0].iov_len = len;        msg.msg_control = cmsg;    msg.msg_controllen = cmsglen;    msg.msg_iov = iov;    msg.msg_iovlen = 1;    msg.msg_name = (void *)&dst_addr;    msg.msg_namelen = sizeof(dst_addr);    /* If we broadcast this message we update the time of last broadcast       to prevent unnecessary broadcasts of HELLO msg's */    //PL:    //PL:debug    //printf("aodv_socket_send is called.\n");#ifdef _IPV6    if (!(memcmp(&dst, &ipv6_multicast_addr, sizeof(ipv6_multicast_addr)))) {#else    if (dst == AODV_BROADCAST) {#endif /* _IPV6 */	gettimeofday(&this_host.bcast_time, NULL);#ifdef NS_PORT	ch->addr_type() = NS_AF_NONE;	sendPacket(p, 0, 0.0);#else		//PL:debug	/*ZJH*/	//printf("send_buf size = %d   send_buf:%s\n", strlen(send_buf),send_buf);	printf("dst_addr.sin6_addr = %s len = %d ttl=%d\n", 	       ip6_to_str(dst_addr.sin6_addr), len,hop_limit);	printf("aodv_socket_send is calling sendmsg.\n");	/*ZJH*/	/*	retval = sendto(dev->sock, send_buf, len, 0,			(struct sockaddr *) &dst_addr, sizeof(dst_addr));	*/	retval = sendmsg(dev->sock, &msg, 0);	if (retval < 0) {	  //PL:#ifdef _IPV6	    log(LOG_WARNING, errno, "aodv_socket_send: Failed send to %s",		ip6_to_str(dst));#else	    log(LOG_WARNING, errno, "aodv_socket_send: Failed send to %s",		ip_to_str(dst));#endif /* _IPV6 */	    return;	}#endif    } else {#ifdef NS_PORT	ch->addr_type() = NS_AF_INET;	/* We trust the decision of next hop for all AODV messages... */	/* Add jitter, even for unicast control messages. */	sendPacket(p, dst, 0.03 * Random::uniform());#else	//PL:debug	/*	printf("aodv_socket_send: sendmsg to not multicast address\n");		retval = sendto(dev->sock, send_buf, len, 0,			(struct sockaddr *) &dst_addr, sizeof(dst_addr));	*/	retval = sendmsg(dev->sock, &msg, 0);	if (retval < 0) {	  //PL:#ifdef _IPV6	    log(LOG_WARNING, errno, "aodv_socket_send: Failed send to %s",		ip6_to_str(dst));#else	    log(LOG_WARNING, errno, "aodv_socket_send: Failed send to %s",		ip_to_str(dst));#endif /* _IPV6 */	    return;	}#endif    }    /* Do not print hello msgs... */    //PL:#ifdef _IPV6    if (!(aodv_msg->type == AODV_RREP && !(memcmp(&dst, &ipv6_multicast_addr,						  sizeof(ipv6_multicast_addr))))){	DEBUG(LOG_INFO, 0,	      "aodv_socket_send: AODV msg to %s hop limit=%d (%d bytes)",	      ip6_to_str(dst), hop_limit, retval);	printf("aodv_socket_send: AODV msg to %s hop limit=%d (%d bytes)\n",	      ip6_to_str(dst), hop_limit, retval);	}#else    if (!(aodv_msg->type == AODV_RREP && (dst == AODV_BROADCAST)))	DEBUG(LOG_INFO, 0,	      "aodv_socket_send: AODV msg to %s ttl=%d (%d bytes)",	      ip_to_str(dst), ttl, retval);#endif /* _IPV6 */}AODV_msg *NS_CLASS aodv_socket_new_msg(void){#if defined(RAW_SOCKET) && !defined(NS_PORT)    struct iphdr *iph;    struct udphdr *udph;    /* Initialize IP header, kernel fills in zero:ed values... */    memset(send_buf, '\0', SEND_BUF_SIZE);    iph = (struct iphdr *) send_buf;    iph->version = IPVERSION;    iph->ihl = (IPHDR_SIZE >> 2);    iph->tos = 0;    iph->id = 0;    iph->frag_off = 0;    iph->protocol = IPPROTO_UDP;    iph->check = 0;    udph = (struct udphdr *) (send_buf + IPHDR_SIZE);    udph->source = htons(AODV_PORT);    udph->dest = htons(AODV_PORT);    udph->check = 0;    return (AODV_msg *) (send_buf + IPHDR_SIZE + sizeof(struct udphdr));#else    memset(send_buf, '\0', SEND_BUF_SIZE);    return (AODV_msg *) (send_buf);#endif				/* RAW_SOCKET */}/* Copy an existing AODV message to the send buffer */AODV_msg *NS_CLASS aodv_socket_queue_msg(AODV_msg * aodv_msg, int size){#if defined(RAW_SOCKET) && !defined(NS_PORT)    memcpy((char *) (send_buf + IPHDR_SIZE), aodv_msg, size);    return (AODV_msg *) (send_buf + IPHDR_SIZE);#else    memcpy((char *) (send_buf), aodv_msg, size);    return (AODV_msg *) (send_buf);#endif				/* RAW_SOCKET */}void aodv_socket_cleanup(void){#ifndef NS_PORT    int i;    for (i = 0; i < MAX_NR_INTERFACES; i++) {	if (!DEV_NR(i).enabled)	    continue;	close(DEV_NR(i).sock);    }#endif				/* NS_PORT */}

⌨️ 快捷键说明

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