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