NETWORK ATTACKS FRAMEWORK  1.0.0
A NETwork Attacks framework. Making network attacks impact evaluation easier!
NA_aodv_uu_omnet.cc
Go to the documentation of this file.
00001 /*****************************************************************************
00002  *
00003  * Copyright (C) 2002 Uppsala University.
00004  * Copyright (C) 2006 Malaga University.
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation; either version 2 of the License, or
00008  * (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018  *
00019  * Authors: Bj�n Wiberg <bjorn.wiberg@home.se>
00020  *          Erik Nordstr� <erik.nordstrom@it.uu.se>
00021  * Authors: Alfonso Ariza Quintana.<aarizaq@uma.ea>
00022  *
00023  *****************************************************************************/
00024 //
00025 // Copyright (C) 2013 and modified by NESG (Network Engineering and Security Group), http://nesg.ugr.es,
00026 // - Gabriel Maciá Fernández (gmacia@ugr.es)
00027 // - Leovigildo Sánchez Casado (sancale@ugr.es)
00028 // - Rafael A. Rodríguez Gómez (rodgom@ugr.es)
00029 // - Roberto Magán Carrión (rmagan@ugr.es)
00030 // - Pedro García Teodoro (pgteodor@ugr.es)
00031 // - José Camacho Páez (josecamacho@ugr.es)
00032 // - Jesús E. Díaz Verdejo (jedv@ugr.es)
00033 //
00034 
00035 #include <string.h>
00036 #include <assert.h>
00037 #include "NA_aodv_uu_omnet.h"
00038 
00039 #include "UDPPacket.h"
00040 #include "IPv4ControlInfo.h"
00041 #include "IPv6ControlInfo.h"
00042 #include "ICMPMessage_m.h"
00043 #include "ICMPAccess.h"
00044 #include "NotifierConsts.h"
00045 #include "IPv4Datagram.h"
00046 #include "IPv4InterfaceData.h"
00047 
00048 #include "ProtocolMap.h"
00049 #include "IPv4Address.h"
00050 #include "IPvXAddress.h"
00051 #include "ControlManetRouting_m.h"
00052 #include "Ieee802Ctrl_m.h"
00053 
00054 
00055 const int UDP_HEADER_BYTES = 8;
00056 typedef std::vector<IPv4Address> IPAddressVector;
00057 
00058 Define_Module(NA_AODVUU);
00059 
00060 /* Constructor for the AODVUU routing agent */
00061 
00062 bool NA_AODVUU::log_file_fd_init=false;
00063 int NA_AODVUU::log_file_fd = -1;
00064 
00065 #ifdef AODV_GLOBAL_STATISTISTIC
00066 bool NA_AODVUU::iswrite = false;
00067 int NA_AODVUU::totalSend=0;
00068 int NA_AODVUU::totalRreqSend=0;
00069 int NA_AODVUU::totalRreqRec=0;
00070 int NA_AODVUU::totalRrepSend=0;
00071 int NA_AODVUU::totalRrepRec=0;
00072 int NA_AODVUU::totalRrepAckSend=0;
00073 int NA_AODVUU::totalRrepAckRec=0;
00074 int NA_AODVUU::totalRerrSend=0;
00075 int NA_AODVUU::totalRerrRec=0;
00076 #endif
00077 
00078 void NS_CLASS initialize(int stage)
00079 {
00080      /*
00081        Enable usage of some of the configuration variables from Tcl.
00082 
00083        Note: Do NOT change the values of these variables in the constructor
00084        after binding them! The desired default values should be set in
00085        ~ns/tcl/lib/ns-default.tcl instead.
00086      */
00087     if (stage==4)
00088     {
00089 #ifndef AODV_GLOBAL_STATISTISTIC
00090         iswrite = false;
00091         totalSend=0;
00092         totalRreqSend=0;
00093         totalRreqRec=0;
00094         totalRrepSend=0;
00095         totalRrepRec=0;
00096         totalRrepAckSend=0;
00097         totalRrepAckRec=0;
00098         totalRerrSend=0;
00099         totalRerrRec=0;
00100 #endif
00101         log_to_file = 0;
00102         hello_jittering = 0;
00103         optimized_hellos = 0;
00104         expanding_ring_search = 0;
00105         local_repair = 0;
00106         debug=0;
00107         rreq_gratuitous =0;
00108 
00109         // BEGIN NA_SINKHOLE - sancale
00110         // Sinkhole attack initialization
00111         sinkholeAttackIsActive = false;
00112         sinkholeAttackProbability = 0;
00113         sinkOnlyWhenRouteInTable = false;
00114         numSents = 0;
00115         // END NA_SINKHOLE - sancale
00116 
00117         //sendMessageEvent = new cMessage();
00118         if ((bool)par("log_to_file"))
00119             log_to_file = 1;
00120 
00121         if ((bool) par("hello_jittering"))
00122             hello_jittering = 1;
00123 
00124         if ((bool)par("optimized_hellos"))
00125             optimized_hellos  = 1;
00126 
00127         if ((bool)par("expanding_ring_search"))
00128             expanding_ring_search = 1;
00129 
00130         if ((bool) par("local_repair"))
00131             local_repair = 1;
00132 
00133         if ((bool)par("rreq_gratuitous"))
00134             rreq_gratuitous = 1;
00135 
00136         if ((bool)par("debug"))
00137             debug = 1;
00138 
00139         useIndex = par("UseIndex");
00140         unidir_hack = (int) par("unidir_hack");
00141 
00142         receive_n_hellos    = (int) par("receive_n_hellos");
00143         wait_on_reboot = (int) par ("wait_on_reboot");
00144         rt_log_interval = (int) par("rt_log_interval"); // Note: in milliseconds!
00145         ratelimit = (int) par("ratelimit");
00146         llfeedback = 0;
00147         if (par("llfeedback"))
00148             llfeedback = 1;
00149         internet_gw_mode = (int) par("internet_gw_mode");
00150         gateWayAddress = new IPv4Address(par("internet_gw_address").stringValue());
00151 
00152         if (llfeedback)
00153         {
00154             active_route_timeout = ACTIVE_ROUTE_TIMEOUT_LLF;
00155             ttl_start = TTL_START_LLF;
00156             delete_period =  DELETE_PERIOD_LLF;
00157         }
00158         else
00159         {
00160             active_route_timeout = (int) par("active_timeout");// ACTIVE_ROUTE_TIMEOUT_HELLO;
00161             ttl_start = TTL_START_HELLO;
00162             delete_period = DELETE_PERIOD_HELLO;
00163         }
00164 
00165         /* Initialize common manet routing protocol structures */
00166         registerRoutingModule();
00167         if (llfeedback)
00168             linkLayerFeeback();
00169 
00170         /* From main.c */
00171         progname = strdup("AODV-UU");
00172         /* From debug.c */
00173         /* Note: log_nmsgs was never used anywhere */
00174         log_nmsgs = 0;
00175         log_rt_fd = -1;
00176 #ifndef  _WIN32
00177 
00178         if (debug && !log_file_fd_init)
00179         {
00180             log_file_fd = -1;
00181             openlog("aodv-uu ",0,LOG_USER);
00182             log_init();
00183             log_file_fd_init=true;
00184         }
00185 #else
00186         debug = 0;
00187 #endif
00188         /* Set host parameters */
00189         memset(&this_host, 0, sizeof(struct host_info));
00190         memset(dev_indices, 0, sizeof(unsigned int) * MAX_NR_INTERFACES);
00191         this_host.seqno = 1;
00192         this_host.rreq_id = 0;
00193         this_host.nif = 1;
00194 
00195 
00196         for (int i = 0; i < MAX_NR_INTERFACES; i++)
00197             DEV_NR(i).enabled=0;
00198 
00199         for (int i = 0; i <getNumInterfaces(); i++)
00200         {
00201             DEV_NR(i).ifindex = i;
00202             dev_indices[i] = i;
00203             strcpy(DEV_NR(i).ifname, getInterfaceEntry(i)->getName());
00204             if (!isInMacLayer())
00205             {
00206                 DEV_NR(i).netmask.s_addr =
00207                     ManetAddress(getInterfaceEntry(i)->ipv4Data()->getIPAddress().getNetworkMask());
00208                 DEV_NR(i).ipaddr.s_addr =
00209                         ManetAddress(getInterfaceEntry(i)->ipv4Data()->getIPAddress());
00210             }
00211             else
00212             {
00213                 DEV_NR(i).netmask.s_addr = ManetAddress(MACAddress::BROADCAST_ADDRESS);
00214                 DEV_NR(i).ipaddr.s_addr = ManetAddress(getInterfaceEntry(i)->getMacAddress());
00215 
00216             }
00217         }
00218         /* Set network interface parameters */
00219         for (int i=0; i < getNumWlanInterfaces(); i++)
00220         {
00221             DEV_NR(getWlanInterfaceIndex(i)).enabled = 1;
00222             DEV_NR(getWlanInterfaceIndex(i)).sock = -1;
00223             DEV_NR(getWlanInterfaceIndex(i)).broadcast.s_addr = ManetAddress(IPv4Address(AODV_BROADCAST));
00224         }
00225 
00226         NS_DEV_NR = getWlanInterfaceIndexByAddress();
00227         NS_IFINDEX = getWlanInterfaceIndexByAddress();
00228 #ifndef AODV_USE_STL
00229         list_t *lista_ptr;
00230         lista_ptr=&rreq_records;
00231         INIT_LIST_HEAD(&rreq_records);
00232         lista_ptr=&rreq_blacklist;
00233         INIT_LIST_HEAD(&rreq_blacklist);
00234         lista_ptr=&seekhead;
00235         INIT_LIST_HEAD(&seekhead);
00236 
00237         lista_ptr=&TQ;
00238         INIT_LIST_HEAD(&TQ);
00239 #endif
00240         /* Initialize data structures */
00241         worb_timer.data = NULL;
00242         worb_timer.used = 0;
00243         hello_timer.data = NULL;
00244         hello_timer.used = 0;
00245         rt_log_timer.data = NULL;
00246         rt_log_timer.used = 0;
00247         isRoot = par("isRoot");
00248         costStatic = par("costStatic");
00249         costMobile = par("costMobile");
00250         useHover = par("useHover");
00251         proactive_rreq_timeout= par("proactiveRreqTimeout").longValue();
00252 
00253         if (isRoot)
00254         {
00255             timer_init(&proactive_rreq_timer,&NS_CLASS rreq_proactive, NULL);
00256             timer_set_timeout(&proactive_rreq_timer, proactive_rreq_timeout);
00257         }
00258 
00259         propagateProactive = par("propagateProactive");
00260         strcpy(nodeName,getParentModule()->getParentModule()->getFullName());
00261         aodv_socket_init();
00262         rt_table_init();
00263         packet_queue_init();
00264         startAODVUUAgent();
00265 
00266         is_init=true;
00267         // Initialize the timer
00268         scheduleNextEvent();
00269         ev << "Aodv active"<< "\n";
00270     }
00271 }
00272 
00273 /* Destructor for the AODV-UU routing agent */
00274 NS_CLASS ~ NA_AODVUU()
00275 {
00276     list_t *tmp = NULL, *pos = NULL;
00277 #ifdef AODV_USE_STL_RT
00278     while (!aodvRtTableMap.empty())
00279     {
00280         free (aodvRtTableMap.begin()->second);
00281         aodvRtTableMap.erase(aodvRtTableMap.begin());
00282     }
00283 #else
00284     for (int i = 0; i < RT_TABLESIZE; i++)
00285     {
00286         list_foreach_safe(pos, tmp, &rt_tbl.tbl[i])
00287         {
00288             rt_table_t *rt = (rt_table_t *) pos;
00289             list_detach(&rt->l);
00290             precursor_list_destroy(rt);
00291             free(rt);
00292         }
00293     }
00294 #endif
00295 #ifndef AODV_USE_STL
00296     while (!list_empty(&rreq_records))
00297     {
00298         pos = list_first(&rreq_records);
00299         list_detach(pos);
00300         if (pos) free(pos);
00301     }
00302 
00303     while (!list_empty(&rreq_blacklist))
00304     {
00305         pos = list_first(&rreq_blacklist);
00306         list_detach(pos);
00307         if (pos) free(pos);
00308     }
00309 
00310     while (!list_empty(&seekhead))
00311     {
00312         pos = list_first(&seekhead);
00313         list_detach(pos);
00314         if (pos) free(pos);
00315     }
00316 #else
00317     while (!rreq_records.empty())
00318     {
00319         free (rreq_records.back());
00320         rreq_records.pop_back();
00321     }
00322 
00323     while (!rreq_blacklist.empty())
00324     {
00325         free (rreq_blacklist.begin()->second);
00326         rreq_blacklist.erase(rreq_blacklist.begin());
00327     }
00328 
00329     while (!seekhead.empty())
00330     {
00331         delete (seekhead.begin()->second);
00332         seekhead.erase(seekhead.begin());
00333     }
00334 #endif
00335     packet_queue_destroy();
00336     cancelAndDelete(sendMessageEvent);
00337     log_cleanup();
00338     delete gateWayAddress;
00339 }
00340 
00341 
00342 /* NETATTACKS: handle menssage from controller. */
00343 void NS_CLASS handleMessageFromAttackController(cMessage *msg){
00344 
00345     // It is necessary to call Enter_Method for doing context switching (4.10 of User Manual)
00346     Enter_Method("NA_AODVUU: handle message from attack controller");
00347 
00348     LOG << "NA_AODVUU: Received message: "<< msg->getFullName() << "\n";
00349 
00350     // BEGIN NA_SINKHOLE - sancale
00351     // Activate sinkhole
00352     if (not strcmp(msg->getFullName(), "sinkholeActivate")) {
00353         NA_SinkholeMessage *dmsg;
00354         dmsg = check_and_cast<NA_SinkholeMessage *>(msg);
00355         LOG << "--> Activating module NA_AODVUU for Sinkhole...\n";
00356         LOG << "    Sinkhole Probability received: "<< dmsg->getSinkholeAttackProbability() << "\n";
00357         LOG << "    Sink only when route in table: " << dmsg->getSinkOnlyWhenRouteInTable() << "\n";
00358         //Now sinkhole attack is activated in this module
00359         sinkholeAttackIsActive = true;
00360         sinkholeAttackProbability = dmsg->getSinkholeAttackProbability();
00361         sinkOnlyWhenRouteInTable = dmsg->getSinkOnlyWhenRouteInTable();
00362         seqnoAdded = dmsg->getSeqnoAdded();
00363         numHops = dmsg->getNumHops();
00364         delete(msg);
00365 
00366         // Deactivate sinkhole
00367     } else if (not strcmp(msg->getFullName(), "sinkholeDeactivate")) {
00368         NA_SinkholeMessage *dmsg;
00369         dmsg = check_and_cast<NA_SinkholeMessage *>(msg);
00370         LOG << "Deactivating module NA_AODVUU for Sinkhole...\n";
00371         //Now sinkholes attack is deactivated
00372         sinkholeAttackIsActive = false;
00373         seqnoAdded = NULL;
00374         numHops = NULL;
00375         delete(msg);
00376      // END NA_SINKHOLE - sancale
00377 
00378     } else {
00379         LOG << "ERROR: Message unknown in NA_AODVUU::handleMessageFromAttackController. Msg: " << msg->getFullName() << "\n";
00380     }
00381 }
00382 
00383 
00384 /*
00385   Moves pending packets with a certain next hop from the interface
00386   queue to the packet buffer or simply drops it.
00387 */
00388 
00389 /* Called for packets whose delivery fails at the link layer */
00390 void NS_CLASS packetFailed(IPv4Datagram *dgram)
00391 {
00392     rt_table_t *rt_next_hop, *rt;
00393     struct in_addr dest_addr, src_addr, next_hop;
00394 
00395     src_addr.s_addr = ManetAddress(dgram->getSrcAddress());
00396     dest_addr.s_addr = ManetAddress(dgram->getDestAddress());
00397 
00398 
00399     DEBUG(LOG_DEBUG, 0, "Got failure callback");
00400     /* We don't care about link failures for broadcast or non-data packets */
00401     if (dgram->getDestAddress().getInt() == IP_BROADCAST ||
00402             dgram->getDestAddress().getInt() == AODV_BROADCAST)
00403     {
00404         DEBUG(LOG_DEBUG, 0, "Ignoring callback");
00405         scheduleNextEvent();
00406         return;
00407     }
00408 
00409 
00410     DEBUG(LOG_DEBUG, 0, "LINK FAILURE for next_hop=%s dest=%s ",ip_to_str(next_hop), ip_to_str(dest_addr));
00411 
00412     if (seek_list_find(dest_addr))
00413     {
00414         DEBUG(LOG_DEBUG, 0, "Ongoing route discovery, buffering packet...");
00415         packet_queue_add((IPv4Datagram *)dgram->dup(), dest_addr);
00416         scheduleNextEvent();
00417         return;
00418     }
00419 
00420 
00421     rt = rt_table_find(dest_addr);
00422 
00423     if (!rt || rt->state == INVALID)
00424     {
00425         scheduleNextEvent();
00426         return;
00427     }
00428     next_hop.s_addr = rt->next_hop.s_addr;
00429     rt_next_hop = rt_table_find(next_hop);
00430 
00431     if (!rt_next_hop || rt_next_hop->state == INVALID)
00432     {
00433         scheduleNextEvent();
00434         return;
00435     }
00436 
00437     /* Do local repair? */
00438     if (local_repair && rt->hcnt <= MAX_REPAIR_TTL)
00439         /* && ch->num_forwards() > rt->hcnt */
00440     {
00441         /* Buffer the current packet */
00442         packet_queue_add((IPv4Datagram *) dgram->dup(), dest_addr);
00443 
00444         // In omnet++ it's not possible to access to the mac queue
00445         //  /* Buffer pending packets from interface queue */
00446         //  interfaceQueue((nsaddr_t) next_hop.s_addr, IFQ_BUFFER);
00447         //  /* Mark the route to be repaired */
00448         rt_next_hop->flags |= RT_REPAIR;
00449         neighbor_link_break(rt_next_hop);
00450         rreq_local_repair(rt, src_addr, NULL);
00451     }
00452     else
00453     {
00454         /* No local repair - just force timeout of link and drop packets */
00455         neighbor_link_break(rt_next_hop);
00456 // In omnet++ it's not possible to access to the mac queue
00457 //  interfaceQueue((nsaddr_t) next_hop.s_addr, IFQ_DROP);
00458     }
00459     scheduleNextEvent();
00460 }
00461 
00462 
00463 /* Called for packets whose delivery fails at the link layer */
00464 void NS_CLASS packetFailedMac(Ieee80211DataFrame *dgram)
00465 {
00466     rt_table_t *rt_next_hop, *rt;
00467     struct in_addr dest_addr, src_addr, next_hop;
00468     if (dgram->getReceiverAddress().isBroadcast())
00469     {
00470         scheduleNextEvent();
00471         return;
00472     }
00473 
00474     src_addr.s_addr = ManetAddress(dgram->getAddress3());
00475     dest_addr.s_addr = ManetAddress(dgram->getAddress4());
00476     if (seek_list_find(dest_addr))
00477     {
00478         DEBUG(LOG_DEBUG, 0, "Ongoing route discovery, buffering packet...");
00479         packet_queue_add(dgram->dup(), dest_addr);
00480         scheduleNextEvent();
00481         return;
00482     }
00483 
00484     rt = rt_table_find(dest_addr);
00485 
00486     if (!rt || rt->state == INVALID)
00487     {
00488         scheduleNextEvent();
00489         return;
00490     }
00491     next_hop.s_addr = rt->next_hop.s_addr;
00492     rt_next_hop = rt_table_find(next_hop);
00493 
00494     if (!rt_next_hop || rt_next_hop->state == INVALID)
00495     {
00496         scheduleNextEvent();
00497         return;
00498     }
00499 
00500     /* Do local repair? */
00501     if (local_repair && rt->hcnt <= MAX_REPAIR_TTL)
00502         /* && ch->num_forwards() > rt->hcnt */
00503     {
00504         /* Buffer the current packet */
00505         packet_queue_add(dgram->dup(), dest_addr);
00506 
00507         // In omnet++ it's not possible to access to the mac queue
00508         //  /* Buffer pending packets from interface queue */
00509         //  interfaceQueue((nsaddr_t) next_hop.s_addr, IFQ_BUFFER);
00510         //  /* Mark the route to be repaired */
00511         rt_next_hop->flags |= RT_REPAIR;
00512         neighbor_link_break(rt_next_hop);
00513         rreq_local_repair(rt, src_addr, NULL);
00514     }
00515     else
00516     {
00517         /* No local repair - just force timeout of link and drop packets */
00518         neighbor_link_break(rt_next_hop);
00519 // In omnet++ it's not possible to access to the mac queue
00520 //  interfaceQueue((nsaddr_t) next_hop.s_addr, IFQ_DROP);
00521     }
00522     scheduleNextEvent();
00523 }
00524 
00525 
00526 
00527 /* Entry-level packet reception */
00528 void NS_CLASS handleMessage (cMessage *msg)
00529 {
00530     AODV_msg *aodvMsg=NULL;
00531     IPv4Datagram * ipDgram=NULL;
00532     UDPPacket * udpPacket=NULL;
00533 
00534     cMessage *msg_aux;
00535     struct in_addr src_addr;
00536     struct in_addr dest_addr;
00537 
00538     if (is_init==false)
00539         opp_error ("Aodv has not been initialized ");
00540     if (msg==sendMessageEvent)
00541     {
00542         // timer event
00543         scheduleNextEvent();
00544         return;
00545     }
00546     /* Handle packet depending on type */
00547     if (dynamic_cast<ControlManetRouting *>(msg))
00548     {
00549         ControlManetRouting * control =  check_and_cast <ControlManetRouting *> (msg);
00550         if (control->getOptionCode()== MANET_ROUTE_NOROUTE)
00551         {
00552             ipDgram = (IPv4Datagram*) control->decapsulate();
00553             cPolymorphic * ctrl = ipDgram->removeControlInfo();
00554             unsigned int ifindex = NS_IFINDEX;  /* Always use ns interface */
00555             if (ctrl)
00556             {
00557                 if (dynamic_cast<Ieee802Ctrl*> (ctrl))
00558                 {
00559                     Ieee802Ctrl *ieeectrl = dynamic_cast<Ieee802Ctrl*> (ctrl);
00560                     ManetAddress address(ieeectrl->getDest());
00561                     int index = getWlanInterfaceIndexByAddress(address);
00562                     if (index!=-1)
00563                         ifindex = index;
00564                 }
00565                 delete ctrl;
00566             }
00567 
00568             EV << "Aodv rec datagram  " << ipDgram->getName() << " with dest=" << ipDgram->getDestAddress().str() << "\n";
00569             processPacket(ipDgram,ifindex);   // Data path
00570         }
00571         else if (control->getOptionCode()== MANET_ROUTE_UPDATE)
00572         {
00573             DEBUG(LOG_DEBUG, 0, "forwarding packers, actualize time outs");
00574             src_addr.s_addr = control->getSrcAddress();
00575             dest_addr.s_addr = control->getDestAddress();
00576             rt_table_t * fwd_rt = rt_table_find(dest_addr);
00577             rt_table_t * rev_rt = rt_table_find(src_addr);
00578             rt_table_update_route_timeouts(fwd_rt, rev_rt);
00579             /* When forwarding data, make sure we are sending HELLO messages */
00580             gettimeofday(&this_host.fwd_time, NULL);
00581         }
00582         delete msg;
00583         scheduleNextEvent();
00584         return;
00585     }
00586     else if (dynamic_cast<UDPPacket *>(msg) || dynamic_cast<AODV_msg  *>(msg))
00587     {
00588         udpPacket = NULL;
00589         if (!isInMacLayer())
00590         {
00591             udpPacket = check_and_cast<UDPPacket*>(msg);
00592             if (udpPacket->getDestinationPort()!= 654)
00593             {
00594                 delete  msg;
00595                 scheduleNextEvent();
00596                 return;
00597             }
00598             msg_aux  = udpPacket->decapsulate();
00599         }
00600         else
00601             msg_aux = msg;
00602 
00603         if (dynamic_cast<AODV_msg  *>(msg_aux))
00604         {
00605             aodvMsg = check_and_cast  <AODV_msg *>(msg_aux);
00606             if (!isInMacLayer())
00607             {
00608                 IPv4ControlInfo *controlInfo = check_and_cast<IPv4ControlInfo*>(udpPacket->removeControlInfo());
00609                 src_addr.s_addr = ManetAddress(controlInfo->getSrcAddr());
00610                 aodvMsg->setControlInfo(controlInfo);
00611             }
00612             else
00613             {
00614                 Ieee802Ctrl *controlInfo = check_and_cast<Ieee802Ctrl*>(udpPacket->getControlInfo());
00615                 src_addr.s_addr = ManetAddress(controlInfo->getSrc());
00616             }
00617         }
00618         else
00619         {
00620             if (udpPacket)
00621                 delete udpPacket;
00622             delete msg_aux;
00623             scheduleNextEvent();
00624             return;
00625 
00626         }
00627 
00628         if (udpPacket)
00629             delete udpPacket;
00630     }
00631     else
00632     {
00633         delete msg;
00634         scheduleNextEvent();
00635         return;
00636     }
00637     /* Detect routing loops */
00638     if (isLocalAddress(src_addr.s_addr))
00639     {
00640         delete aodvMsg;
00641         aodvMsg=NULL;
00642         scheduleNextEvent();
00643         return;
00644     }
00645     recvAODVUUPacket(aodvMsg);
00646     scheduleNextEvent();
00647 }
00648 /*
00649       case PT_ENCAPSULATED:
00650     // Decapsulate...
00651     if (internet_gw_mode) {
00652         rt_table_t *rev_rt, *next_hop_rt;
00653          rev_rt = rt_table_find(saddr);
00654 
00655          if (rev_rt && rev_rt->state == VALID) {
00656          rt_table_update_timeout(rev_rt, ACTIVE_ROUTE_TIMEOUT);
00657 
00658          next_hop_rt = rt_table_find(rev_rt->next_hop);
00659 
00660          if (next_hop_rt && next_hop_rt->state == VALID &&
00661              rev_rt && next_hop_rt->dest_addr.s_addr != rev_rt->dest_addr.s_addr)
00662              rt_table_update_timeout(next_hop_rt, ACTIVE_ROUTE_TIMEOUT);
00663          }
00664          p = pkt_decapsulate(p);
00665 
00666          target_->recv(p, (Handler *)0);
00667          break;
00668     }
00669 
00670     processPacket(p);   // Data path
00671     }
00672 */
00673 
00674 
00675 
00676 /* Starts the AODV-UU routing agent */
00677 int NS_CLASS startAODVUUAgent()
00678 {
00679 
00680     /* Set up the wait-on-reboot timer */
00681     if (wait_on_reboot)
00682     {
00683         timer_init(&worb_timer, &NS_CLASS wait_on_reboot_timeout, &wait_on_reboot);
00684         timer_set_timeout(&worb_timer, DELETE_PERIOD);
00685         DEBUG(LOG_NOTICE, 0, "In wait on reboot for %d milliseconds.",DELETE_PERIOD);
00686     }
00687     /* Schedule the first HELLO */
00688     if (!llfeedback && !optimized_hellos)
00689         hello_start();
00690 
00691     /* Initialize routing table logging */
00692     if (rt_log_interval)
00693         log_rt_table_init();
00694 
00695     /* Initialization complete */
00696     initialized = 1;
00697 
00698     DEBUG(LOG_DEBUG, 0, "Routing agent with IP = %s  started.",
00699           ip_to_str(DEV_NR(NS_DEV_NR).ipaddr));
00700 
00701     DEBUG(LOG_DEBUG, 0, "Settings:");
00702     DEBUG(LOG_DEBUG, 0, "unidir_hack %s", unidir_hack ? "ON" : "OFF");
00703     DEBUG(LOG_DEBUG, 0, "rreq_gratuitous %s", rreq_gratuitous ? "ON" : "OFF");
00704     DEBUG(LOG_DEBUG, 0, "expanding_ring_search %s", expanding_ring_search ? "ON" : "OFF");
00705     DEBUG(LOG_DEBUG, 0, "local_repair %s", local_repair ? "ON" : "OFF");
00706     DEBUG(LOG_DEBUG, 0, "receive_n_hellos %s", receive_n_hellos ? "ON" : "OFF");
00707     DEBUG(LOG_DEBUG, 0, "hello_jittering %s", hello_jittering ? "ON" : "OFF");
00708     DEBUG(LOG_DEBUG, 0, "wait_on_reboot %s", wait_on_reboot ? "ON" : "OFF");
00709     DEBUG(LOG_DEBUG, 0, "optimized_hellos %s", optimized_hellos ? "ON" : "OFF");
00710     DEBUG(LOG_DEBUG, 0, "ratelimit %s", ratelimit ? "ON" : "OFF");
00711     DEBUG(LOG_DEBUG, 0, "llfeedback %s", llfeedback ? "ON" : "OFF");
00712     DEBUG(LOG_DEBUG, 0, "internet_gw_mode %s", internet_gw_mode ? "ON" : "OFF");
00713     DEBUG(LOG_DEBUG, 0, "ACTIVE_ROUTE_TIMEOUT=%d", ACTIVE_ROUTE_TIMEOUT);
00714     DEBUG(LOG_DEBUG, 0, "TTL_START=%d", TTL_START);
00715     DEBUG(LOG_DEBUG, 0, "DELETE_PERIOD=%d", DELETE_PERIOD);
00716 
00717     /* Schedule the first timeout */
00718     scheduleNextEvent();
00719     return 0;
00720 
00721 }
00722 
00723 
00724 
00725 // for use with gateway in the future
00726 IPv4Datagram * NS_CLASS pkt_encapsulate(IPv4Datagram *p, IPv4Address gateway)
00727 {
00728     IPv4Datagram *datagram = new IPv4Datagram(p->getName());
00729     datagram->setByteLength(IP_HEADER_BYTES);
00730     datagram->encapsulate(p);
00731 
00732     // set source and destination address
00733     datagram->setDestAddress(gateway);
00734 
00735     IPv4Address src = p->getSrcAddress();
00736 
00737     // when source address was given, use it; otherwise it'll get the address
00738     // of the outgoing interface after routing
00739     // set other fields
00740     datagram->setTypeOfService(p->getTypeOfService());
00741     datagram->setIdentification(p->getIdentification());
00742     datagram->setMoreFragments(false);
00743     datagram->setDontFragment (p->getDontFragment());
00744     datagram->setFragmentOffset(0);
00745     datagram->setTimeToLive(
00746         p->getTimeToLive() > 0 ?
00747         p->getTimeToLive() :
00748         0);
00749 
00750     datagram->setTransportProtocol(IP_PROT_IP);
00751     return datagram;
00752 }
00753 
00754 
00755 
00756 IPv4Datagram *NS_CLASS pkt_decapsulate(IPv4Datagram *p)
00757 {
00758 
00759     if (p->getTransportProtocol() == IP_PROT_IP)
00760     {
00761         IPv4Datagram *datagram = check_and_cast  <IPv4Datagram *>(p->decapsulate());
00762         datagram->setTimeToLive(p->getTimeToLive());
00763         delete p;
00764         return datagram;
00765     }
00766     return NULL;
00767 }
00768 
00769 
00770 
00771 /*
00772   Reschedules the timer queue timer to go off at the time of the
00773   earliest event (so that the timer queue will be investigated then).
00774   Should be called whenever something might have changed the timer queue.
00775 */
00776 #ifdef AODV_USE_STL
00777 void NS_CLASS scheduleNextEvent()
00778 {
00779     simtime_t timer;
00780     simtime_t timeout = timer_age_queue();
00781 
00782     if (!aodvTimerMap.empty())
00783     {
00784         timer = aodvTimerMap.begin()->first;
00785         if (sendMessageEvent->isScheduled())
00786         {
00787             if (timer < sendMessageEvent->getArrivalTime())
00788             {
00789                 cancelEvent(sendMessageEvent);
00790                 scheduleAt(timer, sendMessageEvent);
00791             }
00792         }
00793         else
00794         {
00795             scheduleAt(timer, sendMessageEvent);
00796         }
00797     }
00798 }
00799 #else
00800 void NS_CLASS scheduleNextEvent()
00801 {
00802     struct timeval *timeout;
00803     double delay;
00804     simtime_t timer;
00805     timeout = timer_age_queue();
00806     if (timeout)
00807     {
00808         delay  = (double)(((double)timeout->tv_usec/(double)1000000.0) +(double)timeout->tv_sec);
00809         timer = simTime()+delay;
00810         if (sendMessageEvent->isScheduled())
00811         {
00812             if (timer < sendMessageEvent->getArrivalTime())
00813             {
00814                 cancelEvent(sendMessageEvent);
00815                 scheduleAt(timer, sendMessageEvent);
00816             }
00817         }
00818         else
00819         {
00820             scheduleAt(timer, sendMessageEvent);
00821         }
00822     }
00823 }
00824 #endif
00825 
00826 
00827 
00828 /*
00829   Replacement for if_indextoname(), used in routing table logging.
00830 */
00831 const char *NS_CLASS if_indextoname(int ifindex, char *ifname)
00832 {
00833     InterfaceEntry *   ie;
00834     assert(ifindex >= 0);
00835     ie = getInterfaceEntry(ifindex);
00836     return ie->getName();
00837 }
00838 
00839 
00840 
00841 void NS_CLASS recvAODVUUPacket(cMessage * msg)
00842 {
00843     struct in_addr src, dst;
00844     int ttl;
00845     int interfaceId;
00846 
00847     AODV_msg *aodv_msg = check_and_cast<AODV_msg *> (msg);
00848     int len = aodv_msg->getByteLength();
00849     int ifIndex=NS_IFINDEX;
00850 
00851     ttl =  aodv_msg->ttl-1;
00852     if (!isInMacLayer())
00853     {
00854         IPv4ControlInfo *ctrl = check_and_cast<IPv4ControlInfo *>(msg->getControlInfo());
00855         IPvXAddress srcAddr = ctrl->getSrcAddr();
00856         IPvXAddress destAddr = ctrl->getDestAddr();
00857 
00858         src.s_addr = ManetAddress(srcAddr);
00859         dst.s_addr =  ManetAddress(destAddr);
00860         interfaceId = ctrl->getInterfaceId();
00861 
00862     }
00863     else
00864     {
00865         Ieee802Ctrl *ctrl = check_and_cast<Ieee802Ctrl *>(msg->getControlInfo());
00866         src.s_addr = ManetAddress(ctrl->getSrc());
00867         dst.s_addr =  ManetAddress(ctrl->getDest());
00868     }
00869 
00870     InterfaceEntry *   ie;
00871     for (int i = 0; i < getNumWlanInterfaces(); i++)
00872     {
00873         ie = getWlanInterfaceEntry(i);
00874         if (!isInMacLayer())
00875         {
00876             IPv4InterfaceData *ipv4data = ie->ipv4Data();
00877             if (interfaceId ==ie->getInterfaceId())
00878                 ifIndex=getWlanInterfaceIndex(i);
00879 
00880             if (ManetAddress(ipv4data->getIPAddress()) == src.s_addr)
00881             {
00882                 delete   aodv_msg;
00883                 return;
00884             }
00885         }
00886         else
00887         {
00888             ManetAddress add(ie->getMacAddress());
00889             if (add== src.s_addr)
00890             {
00891                 delete   aodv_msg;
00892                 return;
00893             }
00894         }
00895     }
00896     aodv_socket_process_packet(aodv_msg, len, src, dst, ttl, ifIndex);
00897     delete   aodv_msg;
00898 }
00899 
00900 
00901 void NS_CLASS processPacket(IPv4Datagram * p,unsigned int ifindex)
00902 {
00903     rt_table_t *fwd_rt, *rev_rt;
00904     struct in_addr dest_addr, src_addr;
00905     u_int8_t rreq_flags = 0;
00906     struct ip_data *ipd = NULL;
00907 
00908 
00909     fwd_rt = NULL;      /* For broadcast we provide no next hop */
00910     ipd = NULL;         /* No ICMP messaging */
00911 
00912     bool isLocal=true;
00913 
00914     src_addr.s_addr = ManetAddress(p->getSrcAddress());
00915     dest_addr.s_addr = ManetAddress(p->getDestAddress());
00916 
00917     InterfaceEntry *   ie;
00918 
00919     if (!p->getSrcAddress().isUnspecified())
00920     {
00921         isLocal = isLocalAddress(ManetAddress(p->getSrcAddress()));
00922     }
00923 
00924     ie = getInterfaceEntry (ifindex);
00925     if (p->getTransportProtocol()==IP_PROT_TCP)
00926         rreq_flags |= RREQ_GRATUITOUS;
00927 
00928     /* If this is a TCP packet and we don't have a route, we should
00929        set the gratuituos flag in the RREQ. */
00930     bool isMcast = ie->ipv4Data()->isMemberOfMulticastGroup(dest_addr.s_addr.getIPv4());
00931 
00932     /* If the packet is not interesting we just let it go through... */
00933     if (isMcast || dest_addr.s_addr == ManetAddress(IPv4Address(AODV_BROADCAST)))
00934     {
00935         send(p,"to_ip");
00936         return;
00937     }
00938     /* Find the entry of the neighboring node and the destination  (if any). */
00939     rev_rt = rt_table_find(src_addr);
00940     fwd_rt = rt_table_find(dest_addr);
00941 
00942 #ifdef CONFIG_GATEWAY
00943     /* Check if we have a route and it is an Internet destination (Should be
00944      * encapsulated and routed through the gateway). */
00945     if (fwd_rt && (fwd_rt->state == VALID) &&
00946             (fwd_rt->flags & RT_INET_DEST))
00947     {
00948         /* The destination should be relayed through the IG */
00949 
00950         rt_table_update_timeout(fwd_rt, ACTIVE_ROUTE_TIMEOUT);
00951 
00952         p = pkt_encapsulate(p, *gateWayAddress);
00953 
00954         if (p == NULL)
00955         {
00956             DEBUG(LOG_ERR, 0, "IP Encapsulation failed!");
00957             return;
00958         }
00959         /* Update pointers to headers */
00960         dest_addr.s_addr = gateWayAddress->getInt();
00961         fwd_rt = rt_table_find(dest_addr);
00962     }
00963 #endif /* CONFIG_GATEWAY */
00964 
00965     /* UPDATE TIMERS on active forward and reverse routes...  */
00966     rt_table_update_route_timeouts(fwd_rt, rev_rt);
00967 
00968     /* OK, the timeouts have been updated. Now see if either: 1. The
00969        packet is for this node -> ACCEPT. 2. The packet is not for this
00970        node -> Send RERR (someone want's this node to forward packets
00971        although there is no route) or Send RREQ. */
00972 
00973     if (!fwd_rt || fwd_rt->state == INVALID ||
00974             (fwd_rt->hcnt == 1 && (fwd_rt->flags & RT_UNIDIR)))
00975     {
00976 
00977         /* Check if the route is marked for repair or is INVALID. In
00978          * that case, do a route discovery. */
00979         struct in_addr rerr_dest;
00980 
00981         // BEGIN NA_SINKHOLE - sancale
00982         // If the sinkhole does not know the route, it does not send RERR
00983         if (sinkholeAttackIsActive) {
00984             if (sinkOnlyWhenRouteInTable == false) {
00985                 LOG << "Sinkhole does not send RERR" << endl;
00986                 cout << simTime() << ": Sinkhole does not send RERR " << endl;
00987                 delete p;
00988                 return;
00989             }
00990         }
00991         // END NA_SINKHOLE - sancale
00992 
00993         if (isLocal)
00994             goto route_discovery;
00995 
00996         if (fwd_rt && (fwd_rt->flags & RT_REPAIR))
00997             goto route_discovery;
00998 
00999 
01000 
01001         RERR *rerr;
01002         DEBUG(LOG_DEBUG, 0,
01003               "No route, src=%s dest=%s prev_hop=%s - DROPPING!",
01004               ip_to_str(src_addr), ip_to_str(dest_addr));
01005         if (fwd_rt)
01006         {
01007             rerr = rerr_create(0, fwd_rt->dest_addr,fwd_rt->dest_seqno);
01008             rt_table_update_timeout(fwd_rt, DELETE_PERIOD);
01009         }
01010         else
01011             rerr = rerr_create(0, dest_addr, 0);
01012         DEBUG(LOG_DEBUG, 0, "Sending RERR to prev hop %s for unknown dest %s",
01013               ip_to_str(src_addr), ip_to_str(dest_addr));
01014 
01015         /* Unicast the RERR to the source of the data transmission
01016          * if possible, otherwise we broadcast it. */
01017 
01018         if (rev_rt && rev_rt->state == VALID)
01019             rerr_dest = rev_rt->next_hop;
01020         else
01021             rerr_dest.s_addr = ManetAddress(IPv4Address(AODV_BROADCAST));
01022 
01023         aodv_socket_send((AODV_msg *) rerr, rerr_dest,RERR_CALC_SIZE(rerr),
01024                          1, &DEV_IFINDEX(ifindex));
01025         if (wait_on_reboot)
01026         {
01027             DEBUG(LOG_DEBUG, 0, "Wait on reboot timer reset.");
01028             timer_set_timeout(&worb_timer, DELETE_PERIOD);
01029         }
01030 
01031         //drop (p);
01032         sendICMP(p);
01033         /* DEBUG(LOG_DEBUG, 0, "Dropping pkt uid=%d", ch->uid()); */
01034         //  icmpAccess.get()->sendErrorMessage(p, ICMP_DESTINATION_UNREACHABLE, 0);
01035         return;
01036 
01037 route_discovery:
01038         /* Buffer packets... Packets are queued by the ip_queue.o
01039            module already. We only need to save the handle id, and
01040            return the proper verdict when we know what to do... */
01041 
01042         packet_queue_add(p, dest_addr);
01043 
01044         if (fwd_rt && (fwd_rt->flags & RT_REPAIR))
01045             rreq_local_repair(fwd_rt, src_addr, ipd);
01046         else
01047             rreq_route_discovery(dest_addr, rreq_flags, ipd);
01048 
01049         return;
01050 
01051     }
01052     else
01053     {
01054         /* DEBUG(LOG_DEBUG, 0, "Sending pkt uid=%d", ch->uid()); */
01055         send(p,"to_ip");
01056         /* When forwarding data, make sure we are sending HELLO messages */
01057         gettimeofday(&this_host.fwd_time, NULL);
01058 
01059         if (!llfeedback && optimized_hellos)
01060             hello_start();
01061     }
01062 }
01063 
01064 
01065 struct dev_info NS_CLASS dev_ifindex (int ifindex)
01066 {
01067     int index = ifindex2devindex(ifindex);
01068     return  (this_host.devs[index]);
01069 }
01070 
01071 struct dev_info NS_CLASS dev_nr(int n)
01072 {
01073     return (this_host.devs[n]);
01074 }
01075 
01076 int NS_CLASS ifindex2devindex(unsigned int ifindex)
01077 {
01078     int i;
01079     for (i = 0; i < this_host.nif; i++)
01080         if (dev_indices[i] == ifindex)
01081             return i;
01082     return -1;
01083 }
01084 
01085 
01086 void NS_CLASS processLinkBreak(const cPolymorphic *details)
01087 {
01088     IPv4Datagram  *dgram=NULL;
01089     if (llfeedback)
01090     {
01091         if (dynamic_cast<IPv4Datagram *>(const_cast<cPolymorphic*> (details)))
01092         {
01093             dgram = check_and_cast<IPv4Datagram *>(details);
01094             packetFailed(dgram);
01095             return;
01096         }
01097         else if (dynamic_cast<Ieee80211DataFrame *>(const_cast<cPolymorphic*> (details)))
01098         {
01099             Ieee80211DataFrame *frame = dynamic_cast<Ieee80211DataFrame *>(const_cast<cPolymorphic*>(details));
01100             packetFailedMac(frame);
01101         }
01102     }
01103 }
01104 
01105 
01106 void NS_CLASS finish()
01107 {
01108 
01109     simtime_t t = simTime();
01110     if (t==0)
01111         return;
01112     if (iswrite)
01113         return;
01114     iswrite=true;
01115     recordScalar("simulated time", t);
01116     recordScalar("Aodv totalSend ", totalSend);
01117     recordScalar("rreq send", totalRreqSend);
01118     recordScalar("rreq rec", totalRreqRec);
01119     recordScalar("rrep send", totalRrepSend);
01120     recordScalar("rrep rec", totalRrepRec);
01121     recordScalar("rrep ack send", totalRrepAckSend);
01122     recordScalar("rrep ack rec", totalRrepAckRec);
01123     recordScalar("rerr send", totalRerrSend);
01124     recordScalar("rerr rec", totalRerrRec);
01125 }
01126 
01127 
01128 uint32_t NS_CLASS getRoute(const ManetAddress &dest,std::vector<ManetAddress> &add)
01129 {
01130     return 0;
01131 }
01132 
01133 
01134 bool  NS_CLASS getNextHop(const ManetAddress &dest,ManetAddress &add, int &iface,double &cost)
01135 {
01136     struct in_addr destAddr;
01137     destAddr.s_addr = dest;
01138     ManetAddress apAddr;
01139     rt_table_t * fwd_rt = this->rt_table_find(destAddr);
01140     if (fwd_rt)
01141     {
01142         if (fwd_rt->state != VALID)
01143             return false;
01144         add = fwd_rt->next_hop.s_addr;
01145         InterfaceEntry * ie = getInterfaceEntry (fwd_rt->ifindex);
01146         iface = ie->getInterfaceId();
01147         cost = fwd_rt->hcnt;
01148         return true;
01149     }
01150     else if (getAp(dest,apAddr))
01151     {
01152         destAddr.s_addr = apAddr;
01153         fwd_rt = this->rt_table_find(destAddr);
01154         if (!fwd_rt)
01155             return false;
01156         if (fwd_rt->state != VALID)
01157             return false;
01158         add = fwd_rt->next_hop.s_addr;
01159         InterfaceEntry * ie = getInterfaceEntry (fwd_rt->ifindex);
01160         iface = ie->getInterfaceId();
01161         cost = fwd_rt->hcnt;
01162         return true;
01163     }
01164     return false;
01165 }
01166 
01167 bool NS_CLASS isProactive()
01168 {
01169     return false;
01170 }
01171 
01172 void NS_CLASS setRefreshRoute(const ManetAddress &destination, const ManetAddress & nextHop,bool isReverse)
01173 {
01174     struct in_addr dest_addr, next_hop;
01175     dest_addr.s_addr = destination;
01176     next_hop.s_addr = nextHop;
01177     rt_table_t * route  = rt_table_find(dest_addr);
01178 
01179     if(par ("checkNextHop").boolValue())
01180     {
01181         if (nextHop.isUnspecified())
01182            return;
01183         if (!isReverse)
01184         {
01185             if (route &&(route->next_hop.s_addr==nextHop))
01186                  rt_table_update_route_timeouts(route, NULL);
01187         }
01188 
01189 
01190         if (isReverse && !route)
01191         {
01192             // Gratuitous Return Path
01193             struct in_addr node_addr;
01194             struct in_addr  ip_src;
01195             node_addr.s_addr = destination;
01196             ip_src.s_addr = nextHop;
01197             rt_table_insert(node_addr, ip_src,0,0, ACTIVE_ROUTE_TIMEOUT, VALID, 0,NS_DEV_NR,0xFFFFFFF,100);
01198         }
01199         else if (route && (route->next_hop.s_addr==nextHop))
01200             rt_table_update_route_timeouts(NULL, route);
01201 
01202     }
01203     else
01204     {
01205         if (!isReverse)
01206         {
01207             if (route)
01208                  rt_table_update_route_timeouts(route, NULL);
01209         }
01210 
01211 
01212         if (isReverse && !route && !nextHop.isUnspecified())
01213         {
01214             // Gratuitous Return Path
01215             struct in_addr node_addr;
01216             struct in_addr  ip_src;
01217             node_addr.s_addr = destination;
01218             ip_src.s_addr = nextHop;
01219             rt_table_insert(node_addr, ip_src,0,0, ACTIVE_ROUTE_TIMEOUT, VALID, 0,NS_DEV_NR,0xFFFFFFF,100);
01220         }
01221         else if (route)
01222             rt_table_update_route_timeouts(NULL, route);
01223 
01224     }
01225 
01226     Enter_Method_Silent();
01227     scheduleNextEvent();
01228 }
01229 
01230 
01231 bool NS_CLASS isOurType(cPacket * msg)
01232 {
01233     AODV_msg *re = dynamic_cast <AODV_msg *>(msg);
01234     if (re)
01235         return true;
01236     return false;
01237 }
01238 
01239 bool NS_CLASS getDestAddress(cPacket *msg,ManetAddress &dest)
01240 {
01241     RREQ *rreq = dynamic_cast <RREQ *>(msg);
01242     if (!rreq)
01243         return false;
01244     dest = rreq->dest_addr;
01245     return true;
01246 
01247 }
01248 #ifdef AODV_USE_STL_RT
01249 bool  NS_CLASS setRoute(const ManetAddress &dest,const ManetAddress &add, const int &ifaceIndex,const int &hops,const ManetAddress &mask)
01250 {
01251     Enter_Method_Silent();
01252     struct in_addr destAddr;
01253     struct in_addr nextAddr;
01254     struct in_addr rerr_dest;
01255     destAddr.s_addr = dest;
01256     nextAddr.s_addr = add;
01257     bool status=true;
01258     bool delEntry = add.isUnspecified();
01259 
01260     DEBUG(LOG_DEBUG, 0, "setRoute %s next hop %s",ip_to_str(destAddr),ip_to_str(nextAddr));
01261 
01262     rt_table_t * fwd_rt = rt_table_find(destAddr);
01263 
01264     if (fwd_rt)
01265     {
01266         if (delEntry)
01267         {
01268             RERR* rerr = rerr_create(0, destAddr, 0);
01269             DEBUG(LOG_DEBUG, 0, "setRoute Sending for unknown dest %s", ip_to_str(destAddr));
01270 
01271             /* Unicast the RERR to the source of the data transmission
01272              * if possible, otherwise we broadcast it. */
01273             rerr_dest.s_addr = ManetAddress(IPv4Address(AODV_BROADCAST));
01274 
01275             aodv_socket_send((AODV_msg *) rerr, rerr_dest,RERR_CALC_SIZE(rerr),
01276                              1, &DEV_IFINDEX(NS_IFINDEX));
01277         }
01278         ManetAddress dest = fwd_rt->dest_addr.s_addr;
01279         AodvRtTableMap::iterator it = aodvRtTableMap.find(dest);
01280         if (it != aodvRtTableMap.end())
01281         {
01282             if (it->second != fwd_rt)
01283                 opp_error("AODV routing table error");
01284         }
01285         aodvRtTableMap.erase(it);
01286         if (fwd_rt->state == VALID || fwd_rt->state == IMMORTAL)
01287             rt_tbl.num_active--;
01288         timer_remove(&fwd_rt->rt_timer);
01289         timer_remove(&fwd_rt->hello_timer);
01290         timer_remove(&fwd_rt->ack_timer);
01291         rt_tbl.num_entries = aodvRtTableMap.size();
01292         free (fwd_rt);
01293     }
01294     else
01295         DEBUG(LOG_DEBUG, 0, "No route entry to delete");
01296 
01297     if (ifaceIndex>=getNumInterfaces())
01298         status = false;
01299     ManetRoutingBase::setRoute(dest,add,ifaceIndex,hops,mask);
01300 
01301     if (!delEntry && ifaceIndex<getNumInterfaces())
01302     {
01303         fwd_rt = modifyAODVTables(destAddr,nextAddr,hops,(uint32_t) SIMTIME_DBL(simTime()), 0xFFFF,IMMORTAL,0, ifaceIndex);
01304         status = (fwd_rt!=NULL);
01305 
01306     }
01307 
01308     return status;
01309 }
01310 
01311 
01312 bool  NS_CLASS setRoute(const ManetAddress &dest,const ManetAddress &add, const char  *ifaceName,const int &hops,const ManetAddress &mask)
01313 {
01314     Enter_Method_Silent();
01315     struct in_addr destAddr;
01316     struct in_addr nextAddr;
01317     struct in_addr rerr_dest;
01318     destAddr.s_addr = dest;
01319     nextAddr.s_addr = add;
01320     bool status=true;
01321     int index;
01322     bool delEntry = add.isUnspecified();
01323 
01324     DEBUG(LOG_DEBUG, 0, "setRoute %s next hop %s",ip_to_str(destAddr),ip_to_str(nextAddr));
01325     rt_table_t * fwd_rt = rt_table_find(destAddr);
01326 
01327     if (fwd_rt)
01328     {
01329         if (delEntry)
01330         {
01331             RERR* rerr = rerr_create(0, destAddr, 0);
01332             DEBUG(LOG_DEBUG, 0, "setRoute Sending for unknown dest %s", ip_to_str(destAddr));
01333 
01334             /* Unicast the RERR to the source of the data transmission
01335              * if possible, otherwise we broadcast it. */
01336             rerr_dest.s_addr = ManetAddress(IPv4Address(AODV_BROADCAST));
01337 
01338             aodv_socket_send((AODV_msg *) rerr, rerr_dest,RERR_CALC_SIZE(rerr),
01339                              1, &DEV_IFINDEX(NS_IFINDEX));
01340         }
01341         ManetAddress dest = fwd_rt->dest_addr.s_addr;
01342         AodvRtTableMap::iterator it = aodvRtTableMap.find(dest);
01343         if (it != aodvRtTableMap.end())
01344         {
01345             if (it->second != fwd_rt)
01346                 opp_error("AODV routing table error");
01347         }
01348         aodvRtTableMap.erase(it);
01349         if (fwd_rt->state == VALID || fwd_rt->state == IMMORTAL)
01350             rt_tbl.num_active--;
01351         timer_remove(&fwd_rt->rt_timer);
01352         timer_remove(&fwd_rt->hello_timer);
01353         timer_remove(&fwd_rt->ack_timer);
01354         rt_tbl.num_entries = aodvRtTableMap.size();
01355         free (fwd_rt);
01356     }
01357     else
01358         DEBUG(LOG_DEBUG, 0, "No route entry to delete");
01359 
01360     for (index = 0; index <getNumInterfaces(); index++)
01361     {
01362         if (strcmp(ifaceName, getInterfaceEntry(index)->getName())==0) break;
01363     }
01364     if (index>=getNumInterfaces())
01365         status = false;
01366 
01367     ManetRoutingBase::setRoute(dest,add,index,hops,mask);
01368 
01369     if (!delEntry && index<getNumInterfaces())
01370     {
01371         fwd_rt = modifyAODVTables(destAddr,nextAddr,hops,(uint32_t) SIMTIME_DBL(simTime()), 0xFFFF,IMMORTAL,0, index);
01372         status = (fwd_rt!=NULL);
01373     }
01374 
01375 
01376     return status;
01377 }
01378 #else
01379 
01380 bool  NS_CLASS setRoute(const ManetAddress &dest,const ManetAddress &add, const int &ifaceIndex,const int &hops,const ManetAddress &mask)
01381 {
01382     Enter_Method_Silent();
01383     struct in_addr destAddr;
01384     struct in_addr nextAddr;
01385     struct in_addr rerr_dest;
01386     destAddr.s_addr = dest;
01387     nextAddr.s_addr = add;
01388     bool status=true;
01389     bool delEntry = (add == (ManetAddress)0);
01390 
01391     DEBUG(LOG_DEBUG, 0, "setRoute %s next hop %s",ip_to_str(destAddr),ip_to_str(nextAddr));
01392 
01393     rt_table_t * fwd_rt = rt_table_find(destAddr);
01394 
01395     if (fwd_rt)
01396     {
01397         if (delEntry)
01398         {
01399             RERR* rerr = rerr_create(0, destAddr, 0);
01400             DEBUG(LOG_DEBUG, 0, "setRoute Sending for unknown dest %s", ip_to_str(destAddr));
01401 
01402             /* Unicast the RERR to the source of the data transmission
01403              * if possible, otherwise we broadcast it. */
01404             rerr_dest.s_addr = AODV_BROADCAST;
01405 
01406             aodv_socket_send((AODV_msg *) rerr, rerr_dest,RERR_CALC_SIZE(rerr),
01407                              1, &DEV_IFINDEX(NS_IFINDEX));
01408         }
01409         list_detach(&fwd_rt->l);
01410         precursor_list_destroy(fwd_rt);
01411         if (fwd_rt->state == VALID || fwd_rt->state == IMMORTAL)
01412             rt_tbl.num_active--;
01413         timer_remove(&fwd_rt->rt_timer);
01414         timer_remove(&fwd_rt->hello_timer);
01415         timer_remove(&fwd_rt->ack_timer);
01416         rt_tbl.num_entries--;
01417         free (fwd_rt);
01418     }
01419     else
01420         DEBUG(LOG_DEBUG, 0, "No route entry to delete");
01421 
01422     if (ifaceIndex>=getNumInterfaces())
01423         status = false;
01424     ManetRoutingBase::setRoute(dest,add,ifaceIndex,hops,mask);
01425 
01426     if (!delEntry && ifaceIndex<getNumInterfaces())
01427     {
01428         fwd_rt = modifyAODVTables(destAddr,nextAddr,hops,(uint32_t) SIMTIME_DBL(simTime()), 0xFFFF,IMMORTAL,0, ifaceIndex);
01429         status = (fwd_rt!=NULL);
01430 
01431     }
01432 
01433     return status;
01434 }
01435 
01436 bool  NS_CLASS setRoute(const ManetAddress &dest,const ManetAddress &add, const char  *ifaceName,const int &hops,const ManetAddress &mask)
01437 {
01438     Enter_Method_Silent();
01439     struct in_addr destAddr;
01440     struct in_addr nextAddr;
01441     struct in_addr rerr_dest;
01442     destAddr.s_addr = dest;
01443     nextAddr.s_addr = add;
01444     bool status=true;
01445     int index;
01446     bool delEntry = (add == (ManetAddress)0);
01447 
01448     DEBUG(LOG_DEBUG, 0, "setRoute %s next hop %s",ip_to_str(destAddr),ip_to_str(nextAddr));
01449     rt_table_t * fwd_rt = rt_table_find(destAddr);
01450 
01451     if (fwd_rt)
01452     {
01453         if (delEntry)
01454         {
01455             RERR* rerr = rerr_create(0, destAddr, 0);
01456             DEBUG(LOG_DEBUG, 0, "setRoute Sending for unknown dest %s", ip_to_str(destAddr));
01457 
01458             /* Unicast the RERR to the source of the data transmission
01459              * if possible, otherwise we broadcast it. */
01460             rerr_dest.s_addr = AODV_BROADCAST;
01461 
01462             aodv_socket_send((AODV_msg *) rerr, rerr_dest,RERR_CALC_SIZE(rerr),
01463                              1, &DEV_IFINDEX(NS_IFINDEX));
01464         }
01465         list_detach(&fwd_rt->l);
01466         precursor_list_destroy(fwd_rt);
01467         if (fwd_rt->state == VALID || fwd_rt->state == IMMORTAL)
01468             rt_tbl.num_active--;
01469         timer_remove(&fwd_rt->rt_timer);
01470         timer_remove(&fwd_rt->hello_timer);
01471         timer_remove(&fwd_rt->ack_timer);
01472         rt_tbl.num_entries--;
01473         free (fwd_rt);
01474     }
01475     else
01476         DEBUG(LOG_DEBUG, 0, "No route entry to delete");
01477 
01478     for (index = 0; index <getNumInterfaces(); index++)
01479     {
01480         if (strcmp(ifaceName, getInterfaceEntry(index)->getName())==0) break;
01481     }
01482     if (index>=getNumInterfaces())
01483         status = false;
01484 
01485     ManetRoutingBase::setRoute(dest,add,index,hops,mask);
01486 
01487     if (!delEntry && index<getNumInterfaces())
01488     {
01489         fwd_rt = modifyAODVTables(destAddr,nextAddr,hops,(uint32_t) SIMTIME_DBL(simTime()), 0xFFFF,IMMORTAL,0, index);
01490         status = (fwd_rt!=NULL);
01491     }
01492 
01493 
01494     return status;
01495 }
01496 #endif
01497 
01498 
 All Classes Files Functions Variables Typedefs Enumerator Defines