NETWORK ATTACKS FRAMEWORK
1.0.0
A NETwork Attacks framework. Making network attacks impact evaluation easier!
|
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