📄 aodv-uu.cc
字号:
/***************************************************************************** * * Copyright (C) 2002 Uppsala University, 2008 Karlstad University * * 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: Bj�rn Wiberg <bjorn.wiberg@home.se> * Erik Nordstr�m <erik.nordstrom@it.uu.se> * Erik Andersson (porting) * Emil Ljungdahl (porting) * * This software is a port of the original AODV-UU packet for NS-2. More info * about AODV-UU at: http://core.it.uu.se/core/index.php/AODV-UU * *****************************************************************************/#include <string.h>#include <assert.h>#include <encap.h>#include <flags.h>#include "aodv-uu.h"/* Method for determining the size of the AODVUU packet header type */int AODV_msg::size(){ return AODV_MSG_MAX_SIZE;}extern packet_t PT_AODVUU;/* Tcl hooks for enabling the AODVUU packet header type */int hdr_aodvuu::offset_;static class AODVUUHeaderClass : public PacketHeaderClass { public: AODVUUHeaderClass():PacketHeaderClass("PacketHeader/AODVUU", AODV_MSG_MAX_SIZE) { this->bind(); bind_offset(&hdr_aodvuu::offset_); }} class_rtProtoAODVUU_hdr;/* Tcl hooks for the AODVUU routing agent */static class AODVUUModuleclass : public TclClass { public: AODVUUModuleclass():TclClass("Module/AODVUU") { } TclObject *create(int argc, const char *const *argv) { return (new AODVUU()); }} class_rtProtoAODVUU;/* Handler for investigating the queue of timers */void TimerQueueTimer::expire(Event *e){ struct timeval *timeout; timeout = agent_->timer_age_queue(); if (timeout) resched((double) timeout->tv_sec + (double) timeout->tv_usec / (double) 1000000);}int NS_CLASS uidcnt_ = 0;/* Constructor for the AODVUU routing agent */NS_CLASS AODVUU() : initialized(0), tqtimer(this), ifqueue(0){ /* Enable usage of some of the configuration variables from Tcl. Note: Do NOT change the values of these variables in the constructor after binding them! The desired default values should be set in ~ns/tcl/lib/ns-default.tcl instead. */ bind("unidir_hack_", &unidir_hack); bind("rreq_gratuitous_", &rreq_gratuitous); bind("expanding_ring_search_", &expanding_ring_search); bind("local_repair_", &local_repair); bind("receive_n_hellos_", &receive_n_hellos); bind("hello_jittering_", &hello_jittering); bind("wait_on_reboot_", &wait_on_reboot); bind("debug_", &debug); bind("rt_log_interval_", &rt_log_interval); // Note: in milliseconds! bind("log_to_file_", &log_to_file); bind("optimized_hellos_", &optimized_hellos); bind("ratelimit_", &ratelimit); bind("llfeedback_", &llfeedback); bind("internet_gw_mode_", &internet_gw_mode); /* Other initializations follow */ /* From main.c */ progname = strdup("AODV-UU"); /* From debug.c */ /* Note: log_nmsgs was never used anywhere */ log_nmsgs = 0; log_file_fd = -1; log_rt_fd = -1; /* Set host parameters */ memset(&this_host, 0, sizeof(struct host_info)); memset(dev_indices, 0, sizeof(unsigned int) * MAX_NR_INTERFACES); this_host.seqno = 1; this_host.rreq_id = 0; node_id = getId(); INIT_LIST_HEAD(&rreq_records); INIT_LIST_HEAD(&rreq_blacklist); INIT_LIST_HEAD(&seekhead); INIT_LIST_HEAD(&TQ); /* Initialize data structures */ worb_timer.data = NULL; worb_timer.used = 0; hello_timer.data = NULL; hello_timer.used = 0; rt_log_timer.data = NULL; rt_log_timer.used = 0; aodv_socket_init(); rt_table_init(); packet_queue_init();}/* Destructor for the AODV-UU routing agent */NS_CLASS ~ AODVUU(){ rt_table_destroy(); log_cleanup();}/* Link layer callback function. Used when link layer packet delivery fails.*/static void link_layer_callback(Packet *p, void *arg){ ((AODVUU *) arg)->packetFailed(p);}/* A small function used as filter to remove packets by destination from the interface queue.*/int ifqueue_filter_on_dest(Packet *p, void *data){ struct hdr_ip *ih = HDR_IP(p); u_int32_t *addr = (u_int32_t *) data; u_int32_t dest_addr = (u_int32_t) ih->daddr(); return (dest_addr == *addr);}/* Moves pending packets with a certain next hop from the interface queue to the packet buffer or simply drops it.*/void NS_CLASS interfaceQueue(nsaddr_t addr, int action){ Packet *q_pkt = NULL; struct hdr_ip *ih = NULL; struct in_addr dest_addr; /* Check that interface queue reference is valid */ if (ifqueues.size() == 0) { DEBUG(LOG_DEBUG, 0, "No assigned ifqueues!!!"); return; } dest_addr.s_addr = addr; /* Move packets from interface queue to packet buffer */ switch (action) { case IFQ_DROP: /* check assigned ifqueues */ for (int i = 0; i < ifqueues.size(); i++) { while ((q_pkt = ifqueues[i]->filter(addr))) { struct hdr_cmn *ch = HDR_CMN(q_pkt); DEBUG(LOG_DEBUG, 0, "Dropping pkt for %s uid=%d", ip_to_str(dest_addr), ch->uid()); drop(q_pkt, 0, DROP_RTR_NO_ROUTE); } } break; case IFQ_DROP_BY_DEST: /* check assigned ifqueues */ for (int i = 0; i < ifqueues.size(); i++) { dest_addr.s_addr = addr; DEBUG(LOG_DEBUG, 0, "Dropping pkts by dest for %s queue_len=%d", ip_to_str(dest_addr), ifqueues[i]->length()); ifqueues[i]->filter(ifqueue_filter_on_dest, (void *) &addr); } break; case IFQ_BUFFER: /* check assigned ifqueues */ for (int i = 0; i < ifqueues.size(); i++) { while ((q_pkt = ifqueues[i]->filter(addr))) { ih = HDR_IP(q_pkt); packet_queue_add(q_pkt, dest_addr); DEBUG(LOG_DEBUG, 0, "Rebuffered IFQ packet"); } } break; default: DEBUG(LOG_DEBUG, 0, "Unspecified action. Don't know what to do."); }}/* Called for packets whose delivery fails at the link layer */void NS_CLASS packetFailed(Packet *p){ struct hdr_cmn *ch = HDR_CMN(p); struct hdr_ip *ih = HDR_IP(p); rt_table_t *rt_next_hop, *rt; struct in_addr dest_addr, src_addr, next_hop; packet_t pt = ch->ptype(); dest_addr.s_addr = ih->daddr(); src_addr.s_addr = ih->saddr(); next_hop.s_addr = ch->next_hop(); DEBUG(LOG_DEBUG, 0, "Got failure callback"); /* We don't care about link failures for broadcast or non-data packets */ if (!(DATA_PACKET(pt) || (pt == PT_PING) || (pt == PT_ENCAPSULATED)) || dest_addr.s_addr == IP_BROADCAST || dest_addr.s_addr == AODV_BROADCAST) { drop(p, 0, DROP_RTR_MAC_CALLBACK); DEBUG(LOG_DEBUG, 0, "Ignoring callback"); goto end; } DEBUG(LOG_DEBUG, 0, "LINK FAILURE for next_hop=%s dest=%s uid=%d", ip_to_str(next_hop), ip_to_str(dest_addr), ch->uid()); if (seek_list_find(dest_addr)) { DEBUG(LOG_DEBUG, 0, "Ongoing route discovery, buffering packet..."); packet_queue_add(p, dest_addr); goto end; } rt_next_hop = rt_table_find(next_hop); rt = rt_table_find(dest_addr); if (!rt_next_hop || rt_next_hop->state == INVALID) goto drop; if (!rt || rt->state == INVALID) goto drop; if (rt->next_hop.s_addr != next_hop.s_addr) { DEBUG(LOG_DEBUG, 0, "next hop mismatch - DROPPING pkt"); drop(p, 0, DROP_RTR_MAC_CALLBACK); goto end; } /* Do local repair? */ if (local_repair && rt->hcnt <= MAX_REPAIR_TTL /* && ch->num_forwards() > rt->hcnt */ ) { /* Buffer the current packet */ packet_queue_add(p, dest_addr); /* Buffer pending packets from interface queue */ interfaceQueue((nsaddr_t) next_hop.s_addr, IFQ_BUFFER); /* Mark the route to be repaired */ rt_next_hop->flags |= RT_REPAIR; neighbor_link_break(rt_next_hop); rreq_local_repair(rt, src_addr, NULL); } else { /* No local repair - just force timeout of link and drop packets */ neighbor_link_break(rt_next_hop); drop: drop(p, 0, DROP_RTR_MAC_CALLBACK); interfaceQueue((nsaddr_t) next_hop.s_addr, IFQ_DROP); } end: /* The link layer event might have changed the timer queue, so we'd better reschedule the timer queue timer... */ scheduleNextEvent();}void NS_CLASS recv(Packet *p){ recv(p, 0);}/* Entry-level packet reception */void NS_CLASS recv(Packet *p, int idSrc){ struct hdr_cmn *ch = HDR_CMN(p); struct hdr_ip *ih = HDR_IP(p); struct in_addr saddr; /* Routing agent must be started before processing packets */ assert(initialized); saddr.s_addr = ih->saddr(); /* Detect routing loops */ for (int i = 0; i < this_host.nif; i++) { if (DEV_NR(i).ipaddr.s_addr == saddr.s_addr && ch->num_forwards() > 0) { drop(p, 0, DROP_RTR_ROUTE_LOOP); goto end; } } /* Handle packet depending on type */ if(ch->ptype() == PT_AODVUU) { recvAODVUUPacket(p, idSrc); // AODV-UU messages (control packets) }#ifdef CONFIG_GATEWAY else if(ch->ptype() == PT_ENCAPSULATED && internet_gw_mode && gw_interface.moduleid != -1) { // Decapsulate... rt_table_t *rev_rt, *next_hop_rt; rev_rt = rt_table_find(saddr); /* Update reverse route */ if (rev_rt && rev_rt->state == VALID) { rt_table_update_timeout(rev_rt, ACTIVE_ROUTE_TIMEOUT); next_hop_rt = rt_table_find(rev_rt->next_hop); if (next_hop_rt && next_hop_rt->state == VALID && rev_rt && next_hop_rt->dest_addr.s_addr != rev_rt->dest_addr.s_addr) rt_table_update_timeout(next_hop_rt, ACTIVE_ROUTE_TIMEOUT); } /* Decapsulate the packet */ p = pkt_decapsulate(p); /* Send to wired target (address classifier) */ sendGwPacket(p); }#endif /* CONFIG_GATEWAY */ else { processPacket(p); // Data path } end: /* Check if any other events are pending and reschedule the timeout */ scheduleNextEvent();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -