NETWORK ATTACKS FRAMEWORK  1.0.0
A NETwork Attacks framework. Making network attacks impact evaluation easier!
NA_routing_table.cc
Go to the documentation of this file.
00001 /*****************************************************************************
00002  *
00003  * Copyright (C) 2001 Uppsala University and Ericsson AB.
00004  *
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: Erik Nordstr�m, <erik.nordstrom@it.uu.se>
00020  *
00021  *****************************************************************************/
00022 #define NS_PORT
00023 #define OMNETPP
00024 
00025 #include <time.h>
00026 #ifdef NS_PORT
00027 #ifndef OMNETPP
00028 #include "ns/aodv-uu.h"
00029 #else
00030 #include "../NA_aodv_uu_omnet.h"
00031 #endif
00032 #else
00033 #include "NA_routing_table.h"
00034 #include "NA_aodv_timeout.h"
00035 #include "NA_aodv_rerr.h"
00036 #include "NA_aodv_hello.h"
00037 #include "NA_aodv_socket.h"
00038 #include "NA_aodv_neighbor.h"
00039 #include "NA_timer_queue_aodv.h"
00040 #include "NA_defs_aodv.h"
00041 #include "NA_debug_aodv.h"
00042 #include "NA_params.h"
00043 #include "NA_seek_list.h"
00044 #include "NA_nl.h"
00045 extern int llfeedback;
00046 #endif              /* NS_PORT */
00047 
00048 #ifndef AODV_USE_STL_RT
00049 static unsigned int hashing(struct in_addr *addr, hash_value * hash);
00050 #endif
00051 
00052 #ifdef AODV_USE_STL_RT
00053 
00054 
00055 void NS_CLASS rt_table_init()
00056 {
00057     while (!aodvRtTableMap.empty())
00058     {
00059         rt_table_delete (aodvRtTableMap.begin()->second);
00060         aodvRtTableMap.erase(aodvRtTableMap.begin());
00061     }
00062     rt_tbl.num_entries = 0;
00063     rt_tbl.num_active = 0;
00064 }
00065 
00066 void NS_CLASS rt_table_destroy()
00067 {
00068     while (!aodvRtTableMap.empty())
00069     {
00070         rt_table_delete (aodvRtTableMap.begin()->second);
00071     }
00072 }
00073 
00074 rt_table_t *NS_CLASS rt_table_insert(struct in_addr dest_addr,
00075                                      struct in_addr next,
00076                                      u_int8_t hops, u_int32_t seqno,
00077                                      u_int32_t life, u_int8_t state,
00078                                      u_int16_t flags, unsigned int ifindex,
00079                                      uint32_t cost,uint8_t hopfix)
00080 {
00081     rt_table_t *rt;
00082     struct in_addr nm;
00083     ManetAddress dest;
00084     nm.s_addr = ManetAddress::ZERO;
00085 
00086     dest = dest_addr.s_addr;
00087     /* Check if we already have an entry for dest_addr */
00088     AodvRtTableMap::iterator it = aodvRtTableMap.find(dest);
00089     if (it != aodvRtTableMap.end())
00090     {
00091         DEBUG(LOG_INFO, 0, "%s already exist in routing table!",
00092               ip_to_str(dest_addr));
00093         return NULL;
00094     }
00095 
00096     ManetAddress apAdd;
00097     if (getAp(dest, apAdd))
00098     {
00099         struct in_addr dest_addrAux;
00100         dest_addrAux.s_addr = apAdd;
00101         rt_table_t * e = rt_table_find(dest_addrAux);
00102         if (e)
00103         {
00104             if (e->next_hop.s_addr != next.s_addr &&
00105                     e->dest_seqno != seqno &&
00106                     e->flags != flags &&
00107                     e->hcnt != hops &&
00108                     e->ifindex != ifindex &&
00109                     e->state != state &&
00110                     e->cost != cost &&
00111                     e->hopfix != hopfix)
00112                 rt_table_update(e, next,hops,  seqno,life,  state, flags, ifindex, cost, hopfix);
00113             return NULL;
00114         }
00115         else
00116             rt = rt_table_insert(dest_addrAux, next,hops,  seqno,life,  state, flags, ifindex, cost, hopfix);
00117         return rt;
00118     }
00119 
00120 
00121     if ((rt = (rt_table_t *) malloc(sizeof(rt_table_t))) == NULL)
00122     {
00123         fprintf(stderr, "Malloc failed!\n");
00124         exit(-1);
00125     }
00126 
00127     memset(rt, 0, sizeof(rt_table_t));
00128     rt->dest_addr = dest_addr;
00129     rt->next_hop = next;
00130     rt->dest_seqno = seqno;
00131     rt->flags = flags;
00132     rt->hcnt = hops;
00133     rt->ifindex = ifindex;
00134     rt->hash = 0;
00135     rt->state = state;
00136     rt->cost = cost;
00137     rt->hopfix = hopfix;
00138 
00139     timer_init(&rt->rt_timer, &NS_CLASS route_expire_timeout, rt);
00140 
00141     timer_init(&rt->ack_timer, &NS_CLASS rrep_ack_timeout, rt);
00142 
00143     timer_init(&rt->hello_timer, &NS_CLASS hello_timeout, rt);
00144 
00145     rt->last_hello_time.tv_sec = 0;
00146     rt->last_hello_time.tv_usec = 0;
00147     rt->hello_cnt = 0;
00148 
00149     rt->nprec = 0;
00150 
00151 
00152     /* Insert first in bucket... */
00153     DEBUG(LOG_INFO, 0, "Inserting %s (bucket %d) next hop %s",
00154           ip_to_str(dest_addr), index, ip_to_str(next));
00155     aodvRtTableMap.insert(std::make_pair(dest,rt));
00156     rt_tbl.num_entries = (int) aodvRtTableMap.size();
00157     if (state == INVALID)
00158     {
00159 
00160         if (flags & RT_REPAIR)
00161         {
00162             rt->rt_timer.handler = &NS_CLASS local_repair_timeout;
00163             life = ACTIVE_ROUTE_TIMEOUT;
00164         }
00165         else
00166         {
00167             rt->rt_timer.handler = &NS_CLASS route_delete_timeout;
00168             life = DELETE_PERIOD;
00169         }
00170 
00171     }
00172     else
00173     {
00174         rt_tbl.num_active++;
00175         /* Add route to omnet inet routing table ... */
00176         nm.s_addr = ManetAddress(IPv4Address::ALLONES_ADDRESS);
00177         if (useIndex)
00178             omnet_chg_rte(dest_addr, next, nm, hops,false,ifindex);
00179         else
00180             omnet_chg_rte(dest_addr, next, nm, hops,false,DEV_NR(ifindex).ipaddr);
00181     }
00182 
00183 #ifdef CONFIG_GATEWAY_DISABLE
00184     if (rt->flags & RT_GATEWAY)
00185         rt_table_update_inet_rt(rt, life);
00186 #endif
00187 
00188 //#ifdef NS_PORT
00189     DEBUG(LOG_INFO, 0, "New timer for %s, life=%d",
00190           ip_to_str(rt->dest_addr), life);
00191 
00192     if (life != 0)
00193         timer_set_timeout(&rt->rt_timer, life);
00194 //#endif
00195     /* In case there are buffered packets for this destination, we
00196      * send them on the new route. */
00197     std::vector<ManetAddress> list;
00198     getListRelatedAp(dest_addr.s_addr, list);
00199     for (unsigned int i = 0; i < list.size(); i++)
00200     {
00201         struct in_addr auxAaddr;
00202         auxAaddr.s_addr = list[i];
00203         if ((rt->state == VALID || rt->state == IMMORTAL)  && seek_list_remove(seek_list_find(auxAaddr)))
00204         {
00205             if (rt->flags & RT_INET_DEST)
00206                 packet_queue_set_verdict(auxAaddr, PQ_ENC_SEND);
00207             else
00208                 packet_queue_set_verdict(auxAaddr, PQ_SEND);
00209         }
00210     }
00211 
00212     if ( state == IMMORTAL)
00213     {
00214         timer_remove(&rt->rt_timer);
00215         timer_remove(&rt->ack_timer);
00216         timer_remove(&rt->hello_timer);
00217     }
00218     return rt;
00219 }
00220 
00221 
00222 rt_table_t *NS_CLASS rt_table_find(struct in_addr dest_addr)
00223 {
00224 
00225     if (aodvRtTableMap.empty())
00226         return NULL;
00227 
00228     /* Check if we already have an entry for dest_addr */
00229     AodvRtTableMap::iterator it = aodvRtTableMap.find(dest_addr.s_addr);
00230 
00231     if (it != aodvRtTableMap.end())
00232         return it->second;
00233     else
00234     {
00235         ManetAddress apAdd;
00236         if (getAp(dest_addr.s_addr, apAdd))
00237         {
00238             it = aodvRtTableMap.find(apAdd);
00239             if (it != aodvRtTableMap.end())
00240                 return it->second;
00241         }
00242         return NULL;
00243     }
00244     return NULL;
00245 }
00246 
00247 rt_table_t *NS_CLASS rt_table_find_gateway()
00248 {
00249     rt_table_t *gw = NULL;
00250     for (AodvRtTableMap::iterator it = aodvRtTableMap.begin(); it != aodvRtTableMap.end(); it++)
00251     {
00252         rt_table_t *rt = it->second;
00253         if ((rt->flags & RT_GATEWAY) && rt->state == VALID)
00254         {
00255             if (!gw || rt->hcnt < gw->hcnt)
00256                 gw = rt;
00257         }
00258     }
00259     return gw;
00260 }
00261 
00262 #ifdef CONFIG_GATEWAY
00263 int NS_CLASS rt_table_update_inet_rt(rt_table_t * gw, u_int32_t life)
00264 {
00265     int n = 0;
00266     int i;
00267 
00268     if (!gw)
00269         return -1;
00270 
00271     for (AodvRtTableMap::iterator it = aodvRtTableMap.begin(); it != aodvRtTableMap.end(); it++)
00272     {
00273         rt_table_t *rt = it->second;
00274         if (rt->flags & RT_INET_DEST && rt->state == VALID)
00275         {
00276             rt_table_update(rt, gw->dest_addr, gw->hcnt, 0, life,
00277                     VALID, rt->flags,rt->ifindex);
00278             n++;
00279         }
00280     }
00281     return n;
00282 }
00283 #endif              /* CONFIG_GATEWAY_DISABLED */
00284 
00285 /* Route expiry and Deletion. */
00286 int NS_CLASS rt_table_invalidate(rt_table_t * rt)
00287 {
00288     struct timeval now;
00289 
00290     gettimeofday(&now, NULL);
00291 
00292     if (rt == NULL)
00293         return -1;
00294 
00295     /* If the route is already invalidated, do nothing... */
00296     if (rt->state == INVALID)
00297     {
00298         DEBUG(LOG_DEBUG, 0, "Route %s already invalidated!!!",
00299               ip_to_str(rt->dest_addr));
00300         return -1;
00301     }
00302 
00303     if (rt->state == IMMORTAL)
00304     {
00305         DEBUG(LOG_DEBUG, 0, "Route %s is immortal!!!",
00306               ip_to_str(rt->dest_addr));
00307         return -1;
00308     }
00309 
00310     if (rt->hello_timer.used)
00311     {
00312         DEBUG(LOG_DEBUG, 0, "last HELLO: %ld",
00313               timeval_diff(&now, &rt->last_hello_time));
00314     }
00315 
00316     /* Remove any pending, but now obsolete timers. */
00317     timer_remove(&rt->rt_timer);
00318     timer_remove(&rt->hello_timer);
00319     timer_remove(&rt->ack_timer);
00320 
00321     /* Mark the route as invalid */
00322     rt->state = INVALID;
00323     rt_tbl.num_active--;
00324 
00325     rt->hello_cnt = 0;
00326 
00327     /* When the lifetime of a route entry expires, increase the sequence
00328        number for that entry. */
00329     seqno_incr(rt->dest_seqno);
00330 
00331     rt->last_hello_time.tv_sec = 0;
00332     rt->last_hello_time.tv_usec = 0;
00333 
00334     /* delete route to omnet inet routing table ... */
00335     /* if delete is true fiels next, hops and mask are nor used */
00336     struct in_addr nm;
00337     nm.s_addr = ManetAddress(IPv4Address::ALLONES_ADDRESS);
00338     omnet_chg_rte(rt->dest_addr, rt->dest_addr, nm, 0,true);
00339 
00340 #ifdef CONFIG_GATEWAY
00341     /* If this was a gateway, check if any Internet destinations were using
00342      * it. In that case update them to use a backup gateway or invalide them
00343      * too. */
00344     if (rt->flags & RT_GATEWAY)
00345     {
00346         int i;
00347 
00348         rt_table_t *gw = rt_table_find_gateway();
00349         for (AodvRtTableMap::iterator it = aodvRtTableMap.begin(); it != aodvRtTableMap.end(); it++)
00350         {
00351             rt_table_t *rt2 = it->second;
00352             if (rt2->state == VALID && (rt2->flags & RT_INET_DEST) && (rt2->next_hop.s_addr == rt->dest_addr.s_addr))
00353             {
00354                 if (0)
00355                 {
00356                     DEBUG(LOG_DEBUG, 0,
00357                             "Invalidated GW %s but found new GW %s for %s",
00358                             ip_to_str(rt->dest_addr),
00359                             ip_to_str(gw->dest_addr),
00360                             ip_to_str(rt2->dest_addr));
00361 #ifdef AODV_USE_STL
00362                     double val  = SIMTIME_DBL(rt->rt_timer.timeout - simTime())*1000.0;
00363                     u_int32_t lifetime = 0;
00364                     if (val >0)
00365                         lifetime = val;
00366                     rt_table_update(rt2, gw->dest_addr, gw->hcnt, 0,
00367                             lifetime, VALID, rt2->flags,rt2->ifindex);
00368 #else
00369                     rt_table_update(rt2, gw->dest_addr, gw->hcnt, 0,
00370                             timeval_diff(&rt->rt_timer.timeout,&now), VALID, rt2->flags,rt2->ifindex);
00371 #endif
00372                 }
00373                 else
00374                 {
00375                     rt_table_invalidate(rt2);
00376                     precursor_list_destroy(rt2);
00377                 }
00378             }
00379         }
00380     }
00381 #endif
00382 
00383     if (rt->flags & RT_REPAIR)
00384     {
00385         /* Set a timeout for the repair */
00386 
00387         rt->rt_timer.handler = &NS_CLASS local_repair_timeout;
00388         timer_set_timeout(&rt->rt_timer, ACTIVE_ROUTE_TIMEOUT);
00389 
00390         DEBUG(LOG_DEBUG, 0, "%s kept for repairs during %u msecs",
00391               ip_to_str(rt->dest_addr), ACTIVE_ROUTE_TIMEOUT);
00392     }
00393     else
00394     {
00395 
00396         /* Schedule a deletion timer */
00397         rt->rt_timer.handler = &NS_CLASS route_delete_timeout;
00398         timer_set_timeout(&rt->rt_timer, DELETE_PERIOD);
00399 
00400         DEBUG(LOG_DEBUG, 0, "%s removed in %u msecs",
00401               ip_to_str(rt->dest_addr), DELETE_PERIOD);
00402     }
00403 
00404     return 0;
00405 }
00406 
00407 void NS_CLASS rt_table_delete(rt_table_t * rt)
00408 {
00409     if (!rt)
00410     {
00411         DEBUG(LOG_ERR, 0, "No route entry to delete");
00412         return;
00413     }
00414 
00415     ManetAddress dest = rt->dest_addr.s_addr;
00416     AodvRtTableMap::iterator it = aodvRtTableMap.find(dest);
00417     if (it != aodvRtTableMap.end())
00418     {
00419         if (it->second != rt)
00420             opp_error("AODV routing table error");
00421     }
00422     aodvRtTableMap.erase(it);
00423 
00424     if (rt->state == VALID || rt->state == IMMORTAL)
00425     {
00426 
00427         /* delete route to omnet inet routing table ... */
00428         /* if delete is true fiels next, hops and mask are nor used */
00429         struct in_addr nm;
00430         nm.s_addr = ManetAddress(IPv4Address::ALLONES_ADDRESS);
00431         omnet_chg_rte(rt->dest_addr, rt->dest_addr, nm, 0,true);
00432         rt_tbl.num_active--;
00433     }
00434     /* Make sure timers are removed... */
00435     timer_remove(&rt->rt_timer);
00436     timer_remove(&rt->hello_timer);
00437     timer_remove(&rt->ack_timer);
00438     rt_tbl.num_entries = (int) aodvRtTableMap.size();
00439     free(rt);
00440     return;
00441 }
00442 
00443 /****************************************************************/
00444 
00445 /* Add an neighbor to the active neighbor list. */
00446 
00447 void NS_CLASS precursor_add(rt_table_t * rt, struct in_addr addr)
00448 {
00449     /* Sanity check */
00450     if (!rt)
00451         return;
00452     for (unsigned int i = 0; i < rt->precursors.size(); i++)
00453     {
00454         if (rt->precursors[i].neighbor.s_addr == addr.s_addr)
00455             return;
00456     }
00457     precursor_t pr;
00458     pr.neighbor.s_addr = addr.s_addr;
00459     rt->precursors.push_back(pr);
00460     rt->nprec = (int)rt->precursors.size();
00461     return;
00462 }
00463 
00464 /****************************************************************/
00465 
00466 /* Remove a neighbor from the active neighbor list. */
00467 
00468 void NS_CLASS precursor_remove(rt_table_t * rt, struct in_addr addr)
00469 {
00470     /* Sanity check */
00471     if (!rt)
00472         return;
00473     for (unsigned int i = 0; i < rt->precursors.size(); i++)
00474     {
00475         if (rt->precursors[i].neighbor.s_addr == addr.s_addr)
00476         {
00477             rt->precursors.erase(rt->precursors.begin()+i);
00478             rt->nprec = (int)rt->precursors.size();
00479             return;
00480         }
00481     }
00482 }
00483 
00484 rt_table_t *NS_CLASS modifyAODVTables(struct in_addr dest_addr,
00485                                       struct in_addr next,
00486                                       u_int8_t hops, u_int32_t seqno,
00487                                       u_int32_t life, u_int8_t state,
00488                                       u_int16_t flags, unsigned int ifindex)
00489 {
00490 
00491     rt_table_t *rt;
00492     struct in_addr nm;
00493     nm.s_addr = ManetAddress::ZERO;
00494 
00495     ManetAddress dest = dest_addr.s_addr;
00496 
00497     DEBUG(LOG_INFO, 0, "modifyAODVTables");
00498     /* Check if we already have an entry for dest_addr */
00499 
00500     if ((rt = (rt_table_t *) malloc(sizeof(rt_table_t))) == NULL)
00501     {
00502         fprintf(stderr, "Malloc failed!\n");
00503         exit(-1);
00504     }
00505     memset(rt, 0, sizeof(rt_table_t));
00506     rt->dest_addr = dest_addr;
00507     rt->next_hop = next;
00508     rt->dest_seqno = seqno;
00509     rt->flags = flags;
00510     rt->hcnt = hops;
00511     rt->ifindex = ifindex;
00512     rt->hash = 0;
00513     rt->state = state;
00514     timer_init(&rt->rt_timer, &NS_CLASS route_expire_timeout, rt);
00515     timer_init(&rt->ack_timer, &NS_CLASS rrep_ack_timeout, rt);
00516     timer_init(&rt->hello_timer, &NS_CLASS hello_timeout, rt);
00517     rt->last_hello_time.tv_sec = 0;
00518     rt->last_hello_time.tv_usec = 0;
00519     rt->hello_cnt = 0;
00520     rt->nprec = 0;
00521 
00522     DEBUG(LOG_INFO, 0, "Inserting %s next hop %s",ip_to_str(dest_addr), ip_to_str(next));
00523 
00524     aodvRtTableMap.insert(std::make_pair(dest,rt));
00525     rt_tbl.num_entries = (int) aodvRtTableMap.size();
00526     if (state == INVALID)
00527     {
00528 
00529         if (flags & RT_REPAIR)
00530         {
00531             rt->rt_timer.handler = &NS_CLASS local_repair_timeout;
00532             life = ACTIVE_ROUTE_TIMEOUT;
00533         }
00534         else
00535         {
00536             rt->rt_timer.handler = &NS_CLASS route_delete_timeout;
00537             life = DELETE_PERIOD;
00538         }
00539     }
00540     else
00541     {
00542         rt_tbl.num_active++;
00543     }
00544 #ifdef CONFIG_GATEWAY_DISABLE
00545     if (rt->flags & RT_GATEWAY)
00546         rt_table_update_inet_rt(rt, life);
00547 #endif
00548 
00549 //#ifdef NS_PORT
00550     DEBUG(LOG_INFO, 0, "New timer for %s, life=%d",
00551           ip_to_str(rt->dest_addr), life);
00552 
00553     if (life != 0)
00554         timer_set_timeout(&rt->rt_timer, life);
00555 //#endif
00556     /* In case there are buffered packets for this destination, we
00557      * send them on the new route. */
00558 
00559     std::vector<ManetAddress> list;
00560     getListRelatedAp(dest_addr.s_addr, list);
00561 
00562     for (unsigned int i = 0; i < list.size(); i++)
00563     {
00564         struct in_addr auxAaddr;
00565         auxAaddr.s_addr = list[i];
00566         if ((rt->state == VALID || rt->state == IMMORTAL) && seek_list_remove(seek_list_find(auxAaddr)))
00567         {
00568             if (rt->flags & RT_INET_DEST)
00569                 packet_queue_set_verdict(auxAaddr, PQ_ENC_SEND);
00570             else
00571                 packet_queue_set_verdict(auxAaddr, PQ_SEND);
00572         }
00573     }
00574     if ( state == IMMORTAL)
00575     {
00576         timer_remove(&rt->rt_timer);
00577         timer_remove(&rt->ack_timer);
00578         timer_remove(&rt->hello_timer);
00579     }
00580     return rt;
00581 }
00582 
00583 void precursor_list_destroy(rt_table_t * rt)
00584 {
00585     /* Sanity check */
00586     if (!rt)
00587         return;
00588     rt->precursors.clear();
00589     rt->nprec=0;
00590 }
00591 
00592 #else
00593 void NS_CLASS rt_table_init()
00594 {
00595     int i;
00596 
00597     rt_tbl.num_entries = 0;
00598     rt_tbl.num_active = 0;
00599 
00600     /* We do a for loop here... NS does not like us to use memset() */
00601     for (i = 0; i < RT_TABLESIZE; i++)
00602     {
00603         INIT_LIST_HEAD(&rt_tbl.tbl[i]);
00604     }
00605 }
00606 
00607 void NS_CLASS rt_table_destroy()
00608 {
00609     int i;
00610     list_t *tmp = NULL, *pos = NULL;
00611 
00612     for (i = 0; i < RT_TABLESIZE; i++)
00613     {
00614         list_foreach_safe(pos, tmp, &rt_tbl.tbl[i])
00615         {
00616             rt_table_t *rt = (rt_table_t *) pos;
00617 
00618             rt_table_delete(rt);
00619         }
00620     }
00621 }
00622 
00623 /* Calculate a hash value and table index given a key... */
00624 unsigned int hashing(struct in_addr *addr, hash_value * hash)
00625 {
00626     /*   *hash = (*addr & 0x7fffffff); */
00627     *hash = (hash_value) addr->s_addr;
00628 
00629     return (*hash & RT_TABLEMASK);
00630 }
00631 
00632 rt_table_t *NS_CLASS rt_table_insert(struct in_addr dest_addr,
00633                                      struct in_addr next,
00634                                      u_int8_t hops, u_int32_t seqno,
00635                                      u_int32_t life, u_int8_t state,
00636                                      u_int16_t flags, unsigned int ifindex,
00637                                      uint32_t cost,uint8_t hopfix)
00638 {
00639     hash_value hash;
00640     unsigned int index;
00641     list_t *pos;
00642     rt_table_t *rt;
00643     struct in_addr nm;
00644     struct in_addr dest;
00645     nm.s_addr = 0;
00646 
00647 
00648 
00649     /* Calculate hash key */
00650     dest.s_addr=dest_addr.s_addr;
00651     index = hashing(&dest, &hash);
00652 
00653     /* Check if we already have an entry for dest_addr */
00654     list_foreach(pos, &rt_tbl.tbl[index])
00655     {
00656         rt = (rt_table_t *) pos;
00657         if (memcmp(&rt->dest_addr, &dest, sizeof(struct in_addr)) == 0)
00658         {
00659             DEBUG(LOG_INFO, 0, "%s already exist in routing table!",
00660                   ip_to_str(dest_addr));
00661             return NULL;
00662         }
00663     }
00664 
00665     if ((rt = (rt_table_t *) malloc(sizeof(rt_table_t))) == NULL)
00666     {
00667         fprintf(stderr, "Malloc failed!\n");
00668         exit(-1);
00669     }
00670 
00671     memset(rt, 0, sizeof(rt_table_t));
00672 
00673     rt->dest_addr = dest_addr;
00674     rt->next_hop = next;
00675     rt->dest_seqno = seqno;
00676     rt->flags = flags;
00677     rt->hcnt = hops;
00678     rt->ifindex = ifindex;
00679     rt->hash = hash;
00680     rt->state = state;
00681     rt->cost = cost;
00682     rt->hopfix = hopfix;
00683 
00684     timer_init(&rt->rt_timer, &NS_CLASS route_expire_timeout, rt);
00685 
00686     timer_init(&rt->ack_timer, &NS_CLASS rrep_ack_timeout, rt);
00687 
00688     timer_init(&rt->hello_timer, &NS_CLASS hello_timeout, rt);
00689 
00690     rt->last_hello_time.tv_sec = 0;
00691     rt->last_hello_time.tv_usec = 0;
00692     rt->hello_cnt = 0;
00693 
00694     rt->nprec = 0;
00695     INIT_LIST_HEAD(&rt->precursors);
00696 
00697     /* Insert first in bucket... */
00698 
00699     rt_tbl.num_entries++;
00700 
00701     DEBUG(LOG_INFO, 0, "Inserting %s (bucket %d) next hop %s",
00702           ip_to_str(dest_addr), index, ip_to_str(next));
00703 
00704     list_add(&rt_tbl.tbl[index], &rt->l);
00705 
00706     if (state == INVALID)
00707     {
00708 
00709         if (flags & RT_REPAIR)
00710         {
00711             rt->rt_timer.handler = &NS_CLASS local_repair_timeout;
00712             life = ACTIVE_ROUTE_TIMEOUT;
00713         }
00714         else
00715         {
00716             rt->rt_timer.handler = &NS_CLASS route_delete_timeout;
00717             life = DELETE_PERIOD;
00718         }
00719 
00720     }
00721     else
00722     {
00723         rt_tbl.num_active++;
00724 #ifndef NS_PORT
00725         nl_send_add_route_msg(dest_addr, next, hops, life, flags,
00726                               ifindex);
00727 #else
00728 #ifdef OMNETPP
00729         /* Add route to omnet inet routing table ... */
00730         nm.s_addr = IPv4Address::ALLONES_ADDRESS;
00731         if (useIndex)
00732             omnet_chg_rte(dest_addr, next, nm, hops,false,ifindex);
00733         else
00734             omnet_chg_rte(dest_addr, next, nm, hops,false,DEV_NR(ifindex).ipaddr);
00735 #endif
00736 #endif
00737     }
00738 
00739 #ifdef CONFIG_GATEWAY_DISABLE
00740     if (rt->flags & RT_GATEWAY)
00741         rt_table_update_inet_rt(rt, life);
00742 #endif
00743 
00744 //#ifdef NS_PORT
00745     DEBUG(LOG_INFO, 0, "New timer for %s, life=%d",
00746           ip_to_str(rt->dest_addr), life);
00747 
00748     if (life != 0)
00749         timer_set_timeout(&rt->rt_timer, life);
00750 //#endif
00751     /* In case there are buffered packets for this destination, we
00752      * send them on the new route. */
00753     std::vector<ManetAddress> list;
00754     getListRelatedAp(dest_addr.s_addr, list);
00755     for (unsigned int i = 0; i < list.size(); i++)
00756     {
00757         struct in_addr auxAaddr;
00758         auxAaddr.s_addr = list[i];
00759         if ((rt->state == VALID || rt->state == IMMORTAL) && seek_list_remove(seek_list_find(auxAaddr)))
00760         {
00761 #ifdef NS_PORT
00762 
00763             if (rt->flags & RT_INET_DEST)
00764                 packet_queue_set_verdict(auxAaddr, PQ_ENC_SEND);
00765             else
00766                 packet_queue_set_verdict(auxAaddr, PQ_SEND);
00767         }
00768 #endif
00769     }
00770 
00771     if ( state == IMMORTAL)
00772     {
00773         timer_remove(&rt->rt_timer);
00774         timer_remove(&rt->ack_timer);
00775         timer_remove(&rt->hello_timer);
00776     }
00777 
00778     return rt;
00779 }
00780 
00781 
00782 rt_table_t *NS_CLASS rt_table_find(struct in_addr dest_addr)
00783 {
00784     hash_value hash;
00785     unsigned int index;
00786     list_t *pos;
00787     struct in_addr dest;
00788 
00789     dest = dest_addr;
00790     if (rt_tbl.num_entries == 0)
00791         return NULL;
00792 
00793     /* Calculate index */
00794     index = hashing(&dest, &hash);
00795 
00796     /* Handle collisions: */
00797     list_foreach(pos, &rt_tbl.tbl[index])
00798     {
00799         rt_table_t *rt = (rt_table_t *) pos;
00800 
00801         if (rt->hash != hash)
00802             continue;
00803 
00804         if (memcmp(&dest_addr, &rt->dest_addr, sizeof(struct in_addr)) == 0)
00805             return rt;
00806 
00807     }
00808     return NULL;
00809 }
00810 
00811 rt_table_t *NS_CLASS rt_table_find_gateway()
00812 {
00813     rt_table_t *gw = NULL;
00814     int i;
00815 
00816     for (i = 0; i < RT_TABLESIZE; i++)
00817     {
00818         list_t *pos;
00819         list_foreach(pos, &rt_tbl.tbl[i])
00820         {
00821             rt_table_t *rt = (rt_table_t *) pos;
00822 
00823             if (rt->flags & RT_GATEWAY && rt->state == VALID)
00824             {
00825                 if (!gw || rt->hcnt < gw->hcnt)
00826                     gw = rt;
00827             }
00828         }
00829     }
00830     return gw;
00831 }
00832 
00833 #ifdef CONFIG_GATEWAY
00834 int NS_CLASS rt_table_update_inet_rt(rt_table_t * gw, u_int32_t life)
00835 {
00836     int n = 0;
00837     int i;
00838 
00839     if (!gw)
00840         return -1;
00841 
00842     for (i = 0; i < RT_TABLESIZE; i++)
00843     {
00844         list_t *pos;
00845         list_foreach(pos, &rt_tbl.tbl[i])
00846         {
00847             rt_table_t *rt = (rt_table_t *) pos;
00848 
00849             if (rt->flags & RT_INET_DEST && rt->state == VALID)
00850             {
00851                 rt_table_update(rt, gw->dest_addr, gw->hcnt, 0, life,
00852                                 VALID, rt->flags,rt->ifindex);
00853                 n++;
00854             }
00855         }
00856     }
00857     return n;
00858 }
00859 #endif              /* CONFIG_GATEWAY_DISABLED */
00860 
00861 /* Route expiry and Deletion. */
00862 int NS_CLASS rt_table_invalidate(rt_table_t * rt)
00863 {
00864     struct timeval now;
00865 
00866     gettimeofday(&now, NULL);
00867 
00868     if (rt == NULL)
00869         return -1;
00870 
00871     /* If the route is already invalidated, do nothing... */
00872     if (rt->state == INVALID)
00873     {
00874         DEBUG(LOG_DEBUG, 0, "Route %s already invalidated!!!",
00875               ip_to_str(rt->dest_addr));
00876         return -1;
00877     }
00878 
00879     if (rt->state == IMMORTAL)
00880     {
00881         DEBUG(LOG_DEBUG, 0, "Route %s is immortal!!!",
00882               ip_to_str(rt->dest_addr));
00883         return -1;
00884     }
00885 
00886     if (rt->hello_timer.used)
00887     {
00888         DEBUG(LOG_DEBUG, 0, "last HELLO: %ld",
00889               timeval_diff(&now, &rt->last_hello_time));
00890     }
00891 
00892     /* Remove any pending, but now obsolete timers. */
00893     timer_remove(&rt->rt_timer);
00894     timer_remove(&rt->hello_timer);
00895     timer_remove(&rt->ack_timer);
00896 
00897     /* Mark the route as invalid */
00898     rt->state = INVALID;
00899     rt_tbl.num_active--;
00900 
00901     rt->hello_cnt = 0;
00902 
00903     /* When the lifetime of a route entry expires, increase the sequence
00904        number for that entry. */
00905     seqno_incr(rt->dest_seqno);
00906 
00907     rt->last_hello_time.tv_sec = 0;
00908     rt->last_hello_time.tv_usec = 0;
00909 
00910 #ifndef NS_PORT
00911     nl_send_del_route_msg(rt->dest_addr, rt->next_hop);
00912 #else
00913 #ifdef OMNETPP
00914     /* delete route to omnet inet routing table ... */
00915     /* if delete is true fiels next, hops and mask are nor used */
00916     struct in_addr nm;
00917     nm.s_addr = IPv4Address::ALLONES_ADDRESS;
00918     omnet_chg_rte(rt->dest_addr, rt->dest_addr, nm, 0,true);
00919 #endif
00920 #endif
00921 
00922 
00923 #ifdef CONFIG_GATEWAY
00924     /* If this was a gateway, check if any Internet destinations were using
00925      * it. In that case update them to use a backup gateway or invalide them
00926      * too. */
00927     if (rt->flags & RT_GATEWAY)
00928     {
00929         int i;
00930 
00931         rt_table_t *gw = rt_table_find_gateway();
00932 
00933         for (i = 0; i < RT_TABLESIZE; i++)
00934         {
00935             list_t *pos;
00936             list_foreach(pos, &rt_tbl.tbl[i])
00937             {
00938                 rt_table_t *rt2 = (rt_table_t *) pos;
00939 
00940                 if (rt2->state == VALID && (rt2->flags & RT_INET_DEST) &&
00941                         (rt2->next_hop.s_addr == rt->dest_addr.s_addr))
00942                 {
00943                     if (0)
00944                     {
00945                         DEBUG(LOG_DEBUG, 0,
00946                               "Invalidated GW %s but found new GW %s for %s",
00947                               ip_to_str(rt->dest_addr),
00948                               ip_to_str(gw->dest_addr),
00949                               ip_to_str(rt2->dest_addr));
00950                         rt_table_update(rt2, gw->dest_addr, gw->hcnt, 0,
00951                                         timeval_diff(&rt->rt_timer.timeout,
00952                                                      &now), VALID, rt2->flags,rt2->ifindex);
00953                     }
00954                     else
00955                     {
00956                         rt_table_invalidate(rt2);
00957                         precursor_list_destroy(rt2);
00958                     }
00959                 }
00960             }
00961         }
00962     }
00963 #endif
00964 
00965     if (rt->flags & RT_REPAIR)
00966     {
00967         /* Set a timeout for the repair */
00968 
00969         rt->rt_timer.handler = &NS_CLASS local_repair_timeout;
00970         timer_set_timeout(&rt->rt_timer, ACTIVE_ROUTE_TIMEOUT);
00971 
00972         DEBUG(LOG_DEBUG, 0, "%s kept for repairs during %u msecs",
00973               ip_to_str(rt->dest_addr), ACTIVE_ROUTE_TIMEOUT);
00974     }
00975     else
00976     {
00977 
00978         /* Schedule a deletion timer */
00979         rt->rt_timer.handler = &NS_CLASS route_delete_timeout;
00980         timer_set_timeout(&rt->rt_timer, DELETE_PERIOD);
00981 
00982         DEBUG(LOG_DEBUG, 0, "%s removed in %u msecs",
00983               ip_to_str(rt->dest_addr), DELETE_PERIOD);
00984     }
00985 
00986     return 0;
00987 }
00988 
00989 void NS_CLASS rt_table_delete(rt_table_t * rt)
00990 {
00991     if (!rt)
00992     {
00993         DEBUG(LOG_ERR, 0, "No route entry to delete");
00994         return;
00995     }
00996 
00997     list_detach(&rt->l);
00998 
00999     precursor_list_destroy(rt);
01000 
01001     if (rt->state == VALID || rt->state == IMMORTAL)
01002     {
01003 
01004 #ifndef NS_PORT
01005         nl_send_del_route_msg(rt->dest_addr, rt->next_hop);
01006 #else
01007 #ifdef OMNETPP
01008         /* delete route to omnet inet routing table ... */
01009         /* if delete is true fiels next, hops and mask are nor used */
01010         struct in_addr nm;
01011         nm.s_addr = IPv4Address::ALLONES_ADDRESS;
01012         omnet_chg_rte(rt->dest_addr, rt->dest_addr, nm, 0,true);
01013 #endif
01014 #endif
01015         rt_tbl.num_active--;
01016     }
01017     /* Make sure timers are removed... */
01018     timer_remove(&rt->rt_timer);
01019     timer_remove(&rt->hello_timer);
01020     timer_remove(&rt->ack_timer);
01021 
01022     rt_tbl.num_entries--;
01023 
01024     free(rt);
01025     return;
01026 }
01027 
01028 /****************************************************************/
01029 
01030 /* Add an neighbor to the active neighbor list. */
01031 
01032 void NS_CLASS precursor_add(rt_table_t * rt, struct in_addr addr)
01033 {
01034     precursor_t *pr;
01035     list_t *pos;
01036 
01037     /* Sanity check */
01038     if (!rt)
01039         return;
01040 
01041     /* Check if the node is already in the precursors list. */
01042     list_foreach(pos, &rt->precursors)
01043     {
01044         pr = (precursor_t *) pos;
01045 
01046         if (pr->neighbor.s_addr == addr.s_addr)
01047             return;
01048     }
01049 
01050     if ((pr = (precursor_t *) malloc(sizeof(precursor_t))) == NULL)
01051     {
01052         perror("Could not allocate memory for precursor node!!\n");
01053         exit(-1);
01054     }
01055 
01056     DEBUG(LOG_INFO, 0, "Adding precursor %s to rte %s",
01057           ip_to_str(addr), ip_to_str(rt->dest_addr));
01058 
01059     pr->neighbor.s_addr = addr.s_addr;
01060 
01061     /* Insert in precursors list */
01062 
01063     list_add(&rt->precursors, &pr->l);
01064     rt->nprec++;
01065 
01066     return;
01067 }
01068 
01069 /****************************************************************/
01070 
01071 /* Remove a neighbor from the active neighbor list. */
01072 
01073 void NS_CLASS precursor_remove(rt_table_t * rt, struct in_addr addr)
01074 {
01075     list_t *pos;
01076 
01077     /* Sanity check */
01078     if (!rt)
01079         return;
01080 
01081     list_foreach(pos, &rt->precursors)
01082     {
01083         precursor_t *pr = (precursor_t *) pos;
01084         if (pr->neighbor.s_addr == addr.s_addr)
01085         {
01086             DEBUG(LOG_INFO, 0, "Removing precursor %s from rte %s",
01087                   ip_to_str(addr), ip_to_str(rt->dest_addr));
01088 
01089             list_detach(pos);
01090             rt->nprec--;
01091             free(pr);
01092             return;
01093         }
01094     }
01095 }
01096 
01097 /****************************************************************/
01098 
01099 /* Delete all entries from the active neighbor list. */
01100 
01101 void precursor_list_destroy(rt_table_t * rt)
01102 {
01103     list_t *pos, *tmp;
01104 
01105     /* Sanity check */
01106     if (!rt)
01107         return;
01108 
01109     list_foreach_safe(pos, tmp, &rt->precursors)
01110     {
01111         precursor_t *pr = (precursor_t *) pos;
01112         list_detach(pos);
01113         rt->nprec--;
01114         free(pr);
01115     }
01116 }
01117 
01118 #ifdef OMNETPP
01119 rt_table_t *NS_CLASS modifyAODVTables(struct in_addr dest_addr,
01120                                       struct in_addr next,
01121                                       u_int8_t hops, u_int32_t seqno,
01122                                       u_int32_t life, u_int8_t state,
01123                                       u_int16_t flags, unsigned int ifindex)
01124 {
01125     hash_value hash;
01126     unsigned int index;
01127     list_t *pos;
01128     rt_table_t *rt;
01129     struct in_addr nm;
01130     struct in_addr dest;
01131     nm.s_addr = 0;
01132 
01133 
01134     /* Calculate hash key */
01135     dest.s_addr=dest_addr.s_addr;
01136     index = hashing(&dest, &hash);
01137 
01138     DEBUG(LOG_INFO, 0, "modifyAODVTables");
01139     /* Check if we already have an entry for dest_addr */
01140     list_foreach(pos, &rt_tbl.tbl[index])
01141     {
01142         rt = (rt_table_t *) pos;
01143         if (memcmp(&rt->dest_addr, &dest, sizeof(struct in_addr)) == 0)
01144         {
01145             DEBUG(LOG_INFO, 0, "%s already exist in routing table!",
01146                   ip_to_str(dest_addr));
01147             return NULL;
01148         }
01149     }
01150 
01151     if ((rt = (rt_table_t *) malloc(sizeof(rt_table_t))) == NULL)
01152     {
01153         fprintf(stderr, "Malloc failed!\n");
01154         exit(-1);
01155     }
01156     memset(rt, 0, sizeof(rt_table_t));
01157     rt->dest_addr = dest_addr;
01158     rt->next_hop = next;
01159     rt->dest_seqno = seqno;
01160     rt->flags = flags;
01161     rt->hcnt = hops;
01162     rt->ifindex = ifindex;
01163     rt->hash = hash;
01164     rt->state = state;
01165     timer_init(&rt->rt_timer, &NS_CLASS route_expire_timeout, rt);
01166     timer_init(&rt->ack_timer, &NS_CLASS rrep_ack_timeout, rt);
01167     timer_init(&rt->hello_timer, &NS_CLASS hello_timeout, rt);
01168     rt->last_hello_time.tv_sec = 0;
01169     rt->last_hello_time.tv_usec = 0;
01170     rt->hello_cnt = 0;
01171     rt->nprec = 0;
01172     INIT_LIST_HEAD(&rt->precursors);
01173     /* Insert first in bucket... */
01174     rt_tbl.num_entries++;
01175     DEBUG(LOG_INFO, 0, "Inserting %s (bucket %d) next hop %s",
01176           ip_to_str(dest_addr), index, ip_to_str(next));
01177 
01178     list_add(&rt_tbl.tbl[index], &rt->l);
01179 
01180     if (state == INVALID)
01181     {
01182 
01183         if (flags & RT_REPAIR)
01184         {
01185             rt->rt_timer.handler = &NS_CLASS local_repair_timeout;
01186             life = ACTIVE_ROUTE_TIMEOUT;
01187         }
01188         else
01189         {
01190             rt->rt_timer.handler = &NS_CLASS route_delete_timeout;
01191             life = DELETE_PERIOD;
01192         }
01193     }
01194     else
01195     {
01196         rt_tbl.num_active++;
01197     }
01198 #ifdef CONFIG_GATEWAY_DISABLE
01199     if (rt->flags & RT_GATEWAY)
01200         rt_table_update_inet_rt(rt, life);
01201 #endif
01202 
01203 //#ifdef NS_PORT
01204     DEBUG(LOG_INFO, 0, "New timer for %s, life=%d",
01205           ip_to_str(rt->dest_addr), life);
01206 
01207     if (life != 0)
01208         timer_set_timeout(&rt->rt_timer, life);
01209 //#endif
01210     /* In case there are buffered packets for this destination, we
01211      * send them on the new route. */
01212     std::vector<ManetAddress> list;
01213     getListRelatedAp(dest_addr.s_addr, list);
01214     for (unsigned int i = 0; i < list.size(); i++)
01215     {
01216         struct in_addr auxAaddr;
01217         auxAaddr.s_addr = list[i];
01218         if ((rt->state == VALID || rt->state == IMMORTAL) && seek_list_remove(seek_list_find(auxAaddr)))
01219         {
01220 #ifdef NS_PORT
01221 
01222             if (rt->flags & RT_INET_DEST)
01223                 packet_queue_set_verdict(auxAaddr, PQ_ENC_SEND);
01224             else
01225                 packet_queue_set_verdict(auxAaddr, PQ_SEND);
01226         }
01227 #endif
01228     }
01229     if ( state == IMMORTAL)
01230     {
01231         timer_remove(&rt->rt_timer);
01232         timer_remove(&rt->ack_timer);
01233         timer_remove(&rt->hello_timer);
01234     }
01235     return rt;
01236 }
01237 #endif
01238 #endif
01239 
01240 rt_table_t *NS_CLASS rt_table_update(rt_table_t * rt, struct in_addr next,
01241                                      u_int8_t hops, u_int32_t seqno,
01242                                      u_int32_t lifetime, u_int8_t state,
01243                                      u_int16_t flags,int iface,uint32_t cost,uint8_t hopfix)
01244 {
01245     struct in_addr nm;
01246     nm.s_addr = ManetAddress::ZERO;
01247 
01248     if ((rt->state == INVALID && state == VALID) || (state == IMMORTAL))
01249     {
01250 
01251         /* If this previously was an expired route, but will now be
01252            active again we must add it to the kernel routing
01253            table... */
01254         if (rt->state == INVALID)
01255             rt_tbl.num_active++;
01256 
01257         if (rt->flags & RT_REPAIR)
01258             flags &= ~RT_REPAIR;
01259         if (iface >=0 && rt->ifindex!=(uint32_t)iface)
01260             rt->ifindex=iface;
01261 
01262 #ifndef NS_PORT
01263         nl_send_add_route_msg(rt->dest_addr, next, hops, lifetime,
01264                               flags, rt->ifindex);
01265 #else
01266 #ifdef OMNETPP
01267         /* Add route to omnet inet routing table ... */
01268         nm.s_addr = ManetAddress(IPv4Address::ALLONES_ADDRESS);
01269         if (useIndex)
01270             omnet_chg_rte(rt->dest_addr, next, nm, hops,false,rt->ifindex);
01271         else
01272             omnet_chg_rte(rt->dest_addr, next, nm, hops,false,DEV_NR(rt->ifindex).ipaddr);
01273 #endif
01274 #endif
01275 
01276     }
01277     else if (!rt->next_hop.s_addr.isUnspecified() &&
01278              rt->next_hop.s_addr != next.s_addr)
01279     {
01280         DEBUG(LOG_INFO, 0, "rt->next_hop=%s, new_next_hop=%s",
01281               ip_to_str(rt->next_hop), ip_to_str(next));
01282         if (iface >=0 && rt->ifindex!=(uint32_t)iface)
01283              rt->ifindex=iface;
01284 #ifndef NS_PORT
01285         nl_send_add_route_msg(rt->dest_addr, next, hops, lifetime,
01286                               flags, rt->ifindex);
01287 #else
01288 #ifdef OMNETPP
01289         /* change route to omnet inet routing table ... */
01290         nm.s_addr = ManetAddress(IPv4Address::ALLONES_ADDRESS);
01291         if (useIndex)
01292             omnet_chg_rte(rt->dest_addr, next, nm, hops,false,rt->ifindex);
01293         else
01294             omnet_chg_rte(rt->dest_addr, next, nm, hops,false,DEV_NR(rt->ifindex).ipaddr);
01295 #endif
01296 #endif
01297     }
01298 
01299     if (hops > 1 && rt->hcnt == 1)
01300     {
01301         rt->last_hello_time.tv_sec = 0;
01302         rt->last_hello_time.tv_usec = 0;
01303         rt->hello_cnt = 0;
01304         timer_remove(&rt->hello_timer);
01305         /* Must also do a "link break" when updating a 1 hop
01306         neighbor in case another routing entry use this as
01307         next hop... */
01308 #ifndef OMNETPP
01309         neighbor_link_break(rt);
01310 #else
01311         // Added in version aodv-uu 0.9.3, it's commented for performance reasons
01312         //  neighbor_link_break(rt);
01313 #endif
01314 
01315     }
01316     rt->flags = flags;
01317     rt->dest_seqno = seqno;
01318     rt->next_hop = next;
01319     rt->hcnt = hops;
01320     rt->cost = cost;
01321     rt->hopfix = hopfix;
01322 
01323 #ifdef CONFIG_GATEWAY
01324     if (rt->flags & RT_GATEWAY)
01325         rt_table_update_inet_rt(rt, lifetime);
01326 #endif
01327 
01328 //#ifdef NS_PORT
01329     if (state != IMMORTAL)
01330     {
01331         rt->rt_timer.handler = &NS_CLASS route_expire_timeout;
01332         if (!(rt->flags & RT_INET_DEST))
01333             rt_table_update_timeout(rt, lifetime);
01334     }
01335     else
01336     {
01337         timer_remove(&rt->rt_timer);
01338         timer_remove(&rt->ack_timer);
01339         timer_remove(&rt->hello_timer);
01340     }
01341 //#endif
01342 
01343     /* Finally, mark as VALID */
01344     rt->state = state;
01345 
01346     /* In case there are buffered packets for this destination, we send
01347      * them on the new route. */
01348     std::vector<ManetAddress> list;
01349     getListRelatedAp(rt->dest_addr.s_addr, list);
01350     for (unsigned int i = 0; i < list.size(); i++)
01351     {
01352         struct in_addr auxAaddr;
01353         auxAaddr.s_addr = list[i];
01354         if ((rt->state == VALID || rt->state == IMMORTAL)&& seek_list_remove(seek_list_find(auxAaddr)))
01355         {
01356 #ifdef NS_PORT
01357 
01358             if (rt->flags & RT_INET_DEST)
01359                 packet_queue_set_verdict(auxAaddr, PQ_ENC_SEND);
01360             else
01361                 packet_queue_set_verdict(auxAaddr, PQ_SEND);
01362         }
01363 #endif
01364     }
01365     return rt;
01366 }
01367 
01368 NS_INLINE rt_table_t *NS_CLASS rt_table_update_timeout(rt_table_t * rt,
01369         u_int32_t lifetime)
01370 {
01371     if (!rt)
01372         return NULL;
01373 
01374     if (rt->state == IMMORTAL)
01375     {
01376         timer_remove(&rt->rt_timer);
01377         timer_remove(&rt->ack_timer);
01378         timer_remove(&rt->hello_timer);
01379         return rt;
01380     }
01381 
01382     if (rt->state == VALID)
01383     {
01384         /* Check if the current valid timeout is larger than the new
01385            one - in that case keep the old one. */
01386         DEBUG(LOG_DEBUG, 0, "Route %s update time out to %d milliseconds",
01387               ip_to_str(rt->dest_addr),lifetime);
01388 
01389 #ifdef AODV_USE_STL
01390         double interval = ((double)lifetime)/1000.0;
01391         simtime_t new_timeout = simTime() + interval;
01392         if (rt->rt_timer.timeout < new_timeout)
01393             timer_set_timeout(&rt->rt_timer, lifetime);
01394 #else
01395         struct timeval new_timeout;
01396         gettimeofday(&new_timeout, NULL);
01397         timeval_add_msec(&new_timeout, lifetime);
01398         if (timeval_diff(&rt->rt_timer.timeout, &new_timeout) < 0)
01399             timer_set_timeout(&rt->rt_timer, lifetime);
01400 #endif
01401     }
01402     else
01403         timer_set_timeout(&rt->rt_timer, lifetime);
01404 
01405     return rt;
01406 }
01407 
01408 /* Update route timeouts in response to an incoming or outgoing data packet. */
01409 void NS_CLASS rt_table_update_route_timeouts(rt_table_t * fwd_rt,
01410         rt_table_t * rev_rt)
01411 {
01412     rt_table_t *next_hop_rt = NULL;
01413 
01414     /* When forwarding a packet, we update the lifetime of the
01415        destination's routing table entry, as well as the entry for the
01416        next hop neighbor (if not the same). AODV draft 10, section
01417        6.2. */
01418 
01419     if (fwd_rt && fwd_rt->state == VALID)
01420     {
01421         if (llfeedback || (fwd_rt->flags & RT_INET_DEST) || fwd_rt->hcnt != 1 || fwd_rt->hello_timer.used)
01422             rt_table_update_timeout(fwd_rt, ACTIVE_ROUTE_TIMEOUT);
01423         next_hop_rt = rt_table_find(fwd_rt->next_hop);
01424 
01425         if (next_hop_rt && next_hop_rt->state == VALID &&
01426                 next_hop_rt->dest_addr.s_addr != fwd_rt->dest_addr.s_addr &&
01427                 (llfeedback || fwd_rt->hello_timer.used))
01428             rt_table_update_timeout(next_hop_rt, ACTIVE_ROUTE_TIMEOUT);
01429 
01430     }
01431     /* Also update the reverse route and reverse next hop along the
01432        path back, since routes between originators and the destination
01433        are expected to be symmetric. */
01434     if (rev_rt && rev_rt->state == VALID)
01435     {
01436 
01437         if (llfeedback || rev_rt->hcnt != 1 || rev_rt->hello_timer.used)
01438             rt_table_update_timeout(rev_rt, ACTIVE_ROUTE_TIMEOUT);
01439 
01440         next_hop_rt = rt_table_find(rev_rt->next_hop);
01441 
01442         if (next_hop_rt && next_hop_rt->state == VALID && rev_rt &&
01443                 next_hop_rt->dest_addr.s_addr != rev_rt->dest_addr.s_addr &&
01444                 (llfeedback || rev_rt->hello_timer.used))
01445             rt_table_update_timeout(next_hop_rt, ACTIVE_ROUTE_TIMEOUT);
01446 
01447         /* Update HELLO timer of next hop neighbor if active */
01448         /*  if (!llfeedback && next_hop_rt->hello_timer.used) { */
01449         /*      struct timeval now; */
01450 
01451         /*      gettimeofday(&now, NULL); */
01452         /*      hello_update_timeout(next_hop_rt, &now,  */
01453         /*               ALLOWED_HELLO_LOSS * HELLO_INTERVAL); */
01454         /*  } */
01455     }
01456 }
01457 
01458 
 All Classes Files Functions Variables Typedefs Enumerator Defines