📄 aodv_socket.c
字号:
aodv_socket_process_packet(aodv_msg, len, src, dst, ttl, NS_IFINDEX);}#elsestatic void aodv_socket_read(int fd){ struct in_addr src, dst; int i, len, ttl; AODV_msg *aodv_msg; int iph_len; struct iphdr *ip; struct udphdr *udp; struct dev_info *dev; len = recvfrom(fd, recv_buf, RECV_BUF_SIZE, 0, NULL, NULL); if (len < 0 || len < IPHDR_SIZE) { alog(LOG_WARNING, 0, __FUNCTION__, "receive ERROR!"); return; } /* Parse the IP header */ ip = (struct iphdr *) recv_buf; src.s_addr = ip->saddr; dst.s_addr = ip->daddr; ttl = ip->ttl; iph_len = ip->ihl << 2; udp = (struct udphdr *) (recv_buf + iph_len); if (ntohs(udp->dest) != AODV_PORT && ntohs(udp->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(struct in_addr)) == 0) return; aodv_msg = (AODV_msg *) (recv_buf + iph_len + sizeof(struct udphdr)); len = ntohs(udp->len) - sizeof(struct udphdr); dev = devfromsock(fd); if (!dev) { DEBUG(LOG_ERR, 0, "Could not get device info!\n"); return; }#ifdef USE_IW_SPY if (spy_addrs && link_qual_get_from_ip(src, dev->ifname) < hello_qual_threshold) return;#endif /* USE_IW_SPY */ aodv_socket_process_packet(aodv_msg, len, src, dst, ttl, dev->ifindex);}#endif /* NS_PORT */void NS_CLASS aodv_socket_send(AODV_msg * aodv_msg, struct in_addr dst, int len, u_int8_t ttl, struct dev_info *dev){ int retval = 0; struct timeval now; /* Rate limit stuff: */ #ifndef NS_PORT int totlen = 0; struct sockaddr_in dst_addr; struct iphdr *ip; struct udphdr *udp; 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". */ totlen = sizeof(struct iphdr) + sizeof(struct udphdr) + len; ip = (struct iphdr *) send_buf; ip->version = IPVERSION; ip->ihl = sizeof(struct iphdr) >> 2; ip->tos |= IPTOS_PREC_NETCONTROL | IPTOS_LOWDELAY; /* Highest priority */ ip->tot_len = htons(totlen); ip->id = 0; /* Let IP set */ ip->frag_off = htons(0x4000); /* Set Do Not Fragment bit */ ip->ttl = ttl; ip->protocol = IPPROTO_UDP; ip->saddr = dev->ipaddr.s_addr; ip->daddr = dst.s_addr; ip->check = 0; /* Let kernel calculate */ udp = (struct udphdr *) (send_buf + sizeof(struct iphdr)); udp->source = htons(AODV_PORT); udp->dest = htons(AODV_PORT); udp->len = htons(len + sizeof(struct udphdr)); udp->check = in_udp_csum(ip->saddr, ip->daddr, udp->len, ip->protocol, (unsigned short *)udp); memset(&dst_addr, 0, sizeof(dst_addr)); dst_addr.sin_family = AF_INET; dst_addr.sin_addr = dst; dst_addr.sin_port = htons(AODV_PORT);#else /* 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.s_addr; // Set IP header fields ih->saddr() = (nsaddr_t) dev->ipaddr.s_addr; ih->daddr() = (nsaddr_t) dst.s_addr; 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 */ /* If rate limiting is enabled, check if we are sending either a RREQ or a RERR. In that case, drop the outgoing control packet if the time since last transmit of that type of packet is less than the allowed RATE LIMIT time... */ if (ratelimit) { gettimeofday(&now, NULL); switch (aodv_msg->type) { case AODV_RREQ: if (num_rreq == (RREQ_RATELIMIT - 1)) { if (timeval_diff(&now, &rreq_ratel[0]) < 1000) { DEBUG(LOG_DEBUG, 0, "RATELIMIT: Dropping RREQ %ld ms", timeval_diff(&now, &rreq_ratel[0])); return; } else { memmove(rreq_ratel, &rreq_ratel[1], sizeof(struct timeval) * (num_rreq - 1)); memcpy(&rreq_ratel[num_rreq - 1], &now, sizeof(struct timeval)); } } else { memcpy(&rreq_ratel[num_rreq], &now, sizeof(struct timeval)); num_rreq++; } break; case AODV_RERR: if (num_rerr == (RERR_RATELIMIT - 1)) { if (timeval_diff(&now, &rerr_ratel[0]) < 1000) { DEBUG(LOG_DEBUG, 0, "RATELIMIT: Dropping RERR %ld ms", timeval_diff(&now, &rerr_ratel[0])); return; } else { memmove(rerr_ratel, &rerr_ratel[1], sizeof(struct timeval) * (num_rerr - 1)); memcpy(&rerr_ratel[num_rerr - 1], &now, sizeof(struct timeval)); } } else { memcpy(&rerr_ratel[num_rerr], &now, sizeof(struct timeval)); num_rerr++; } break; } } /* If we broadcast this message we update the time of last broadcast to prevent unnecessary broadcasts of HELLO msg's */ if (dst.s_addr == AODV_BROADCAST) { gettimeofday(&this_host.bcast_time, NULL);#ifdef NS_PORT ch->addr_type() = NS_AF_NONE; sendPacket(p, dst, 0.0);#else retval = sendto(dev->sock, send_buf, totlen, 0, (struct sockaddr *) &dst_addr, sizeof(dst_addr)); if (retval < 0) { alog(LOG_WARNING, errno, __FUNCTION__, "Failed send to %s", ip_to_str(dst)); return; }#endif } else {#ifdef NS_PORT ch->addr_type() = NS_AF_INET; /* We trust the decision of next hop for all AODV messages... */ if (dst.s_addr == AODV_BROADCAST) sendPacket(p, dst, 0.001 * Random::uniform()); else sendPacket(p, dst, 0.0);#else retval = sendto(dev->sock, send_buf, totlen, 0, (struct sockaddr *) &dst_addr, sizeof(dst_addr)); if (retval < 0) { alog(LOG_WARNING, errno, __FUNCTION__, "Failed send to %s", ip_to_str(dst)); return; }#endif } /* Do not print hello msgs... */ if (!(aodv_msg->type == AODV_RREP && (dst.s_addr == AODV_BROADCAST))) DEBUG(LOG_INFO, 0, "AODV msg to %s ttl=%d size=%u", ip_to_str(dst), ttl, retval, len); return;}AODV_msg *NS_CLASS aodv_socket_new_msg(void){#ifndef NS_PORT /* Initialize IP header, kernel fills in zero:ed values... */ memset(send_buf, '\0', SEND_BUF_SIZE); return (AODV_msg *) (send_buf + IPHDR_SIZE + sizeof(struct udphdr));#else memset(send_buf, '\0', SEND_BUF_SIZE); return (AODV_msg *) (send_buf);#endif }/* Copy an existing AODV message to the send buffer */AODV_msg *NS_CLASS aodv_socket_queue_msg(AODV_msg * aodv_msg, int size){#ifndef NS_PORT memcpy((char *) (send_buf + IPHDR_SIZE + sizeof(struct udphdr)), aodv_msg, size); return (AODV_msg *) (send_buf + IPHDR_SIZE + sizeof(struct udphdr));#else memcpy((char *) send_buf, aodv_msg, size); return (AODV_msg *) send_buf;#endif }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 + -