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�, <erik.nordstrom@it.uu.se> 00020 * 00021 * 00022 *****************************************************************************/ 00023 // 00024 // Copyright (C) 2013 and modified by NESG (Network Engineering and Security Group), http://nesg.ugr.es, 00025 // - Gabriel Maciá Fernández (gmacia@ugr.es) 00026 // - Leovigildo Sánchez Casado (sancale@ugr.es) 00027 // - Rafael A. Rodríguez Gómez (rodgom@ugr.es) 00028 // - Roberto Magán Carrión (rmagan@ugr.es) 00029 // - Pedro García Teodoro (pgteodor@ugr.es) 00030 // - José Camacho Páez (josecamacho@ugr.es) 00031 // - Jesús E. Díaz Verdejo (jedv@ugr.es) 00032 // 00033 00034 #define NS_PORT 00035 #define OMNETPP 00036 00037 #ifdef NS_PORT 00038 #ifndef OMNETPP 00039 #include "ns/aodv-uu.h" 00040 #else 00041 #include "../NA_aodv_uu_omnet.h" 00042 #endif 00043 #else 00044 #include <netinet/in.h> 00045 00046 #include "NA_aodv_rreq.h" 00047 #include "NA_aodv_rrep.h" 00048 #include "NA_routing_table.h" 00049 #include "NA_aodv_timeout.h" 00050 #include "NA_timer_queue_aodv.h" 00051 #include "NA_aodv_socket.h" 00052 #include "NA_params.h" 00053 #include "NA_seek_list.h" 00054 #include "NA_defs_aodv.h" 00055 #include "NA_debug_aodv.h" 00056 00057 #include "NA_locality.h" 00058 #endif 00059 00060 // BEGIN NA_SINKHOLE - sancale 00061 // IP resolving. 00062 #include <IPvXAddressResolver.h> 00063 // Maximum sequence number. 00064 #define MAX_SEQ 4294967295 00065 // END NA_SINKHOLE - sancale 00066 00067 /* Comment this to remove packet field output: */ 00068 //#define DEBUG_OUTPUT 00069 00070 #define HCNT_LIMIT 0 00071 00072 #ifndef NS_PORT 00073 static LIST(rreq_records); 00074 static LIST(rreq_blacklist); 00075 00076 static struct rreq_record *rreq_record_insert(struct in_addr orig_addr, 00077 u_int32_t rreq_id); 00078 static struct rreq_record *rreq_record_find(struct in_addr orig_addr, 00079 u_int32_t rreq_id); 00080 00081 struct blacklist *rreq_blacklist_find(struct in_addr dest_addr); 00082 00083 extern int rreq_gratuitous, expanding_ring_search; 00084 extern int internet_gw_mode; 00085 #endif 00086 00087 00112 RREQ *NS_CLASS rreq_create(u_int8_t flags,struct in_addr dest_addr, 00113 u_int32_t dest_seqno, struct in_addr orig_addr) 00114 { 00115 RREQ *rreq; 00116 #ifndef OMNETPP 00117 rreq = (RREQ *) aodv_socket_new_msg(); 00118 #else 00119 rreq = new RREQ(); 00120 rreq->cost=0; 00121 #endif 00122 rreq->type = AODV_RREQ; 00123 rreq->res1 = 0; 00124 rreq->res2 = 0; 00125 rreq->hcnt = 0; 00126 rreq->rreq_id = htonl(this_host.rreq_id++); 00127 rreq->dest_addr = dest_addr.s_addr; 00128 rreq->dest_seqno = htonl(dest_seqno); 00129 rreq->orig_addr = orig_addr.s_addr; 00130 00131 /* Immediately before a node originates a RREQ flood it must 00132 increment its sequence number... */ 00133 seqno_incr(this_host.seqno); 00134 rreq->orig_seqno = htonl(this_host.seqno); 00135 00136 if (flags & RREQ_JOIN) 00137 rreq->j = 1; 00138 if (flags & RREQ_REPAIR) 00139 rreq->r = 1; 00140 if (flags & RREQ_GRATUITOUS) 00141 rreq->g = 1; 00142 if (flags & RREQ_DEST_ONLY) 00143 rreq->d = 1; 00144 00145 DEBUG(LOG_DEBUG, 0, "Assembled RREQ %s", ip_to_str(dest_addr)); 00146 #ifdef DEBUG_OUTPUT 00147 log_pkt_fields((AODV_msg *) rreq); 00148 #endif 00149 00150 return rreq; 00151 } 00152 00153 AODV_ext *rreq_add_ext(RREQ * rreq, int type, unsigned int offset, 00154 int len, char *data) 00155 { 00156 AODV_ext *ext = NULL; 00157 #ifndef OMNETPP 00158 if (offset < RREQ_SIZE) 00159 return NULL; 00160 00161 ext = (AODV_ext *) ((char *) rreq + offset); 00162 00163 ext->type = type; 00164 ext->length = len; 00165 00166 memcpy(AODV_EXT_DATA(ext), data, len); 00167 #else 00168 ext = rreq->addExtension(type,len,data); 00169 #endif 00170 return ext; 00171 } 00172 00173 void NS_CLASS rreq_send(struct in_addr dest_addr, u_int32_t dest_seqno, 00174 int ttl, u_int8_t flags) 00175 { 00176 RREQ *rreq; 00177 struct in_addr dest; 00178 int i; 00179 dest.s_addr = ManetAddress(IPv4Address(AODV_BROADCAST)); 00180 /* Check if we should force the gratuitous flag... (-g option). */ 00181 if (rreq_gratuitous) 00182 flags |= RREQ_GRATUITOUS; 00183 00184 /* Broadcast on all interfaces */ 00185 #ifdef OMNETPP 00186 double delay = -1; 00187 if (par("EqualDelay")) 00188 delay = par("broadcastDelay"); 00189 #endif 00190 00191 for (i = 0; i < MAX_NR_INTERFACES; i++) 00192 { 00193 if (!DEV_NR(i).enabled) 00194 continue; 00195 rreq = rreq_create(flags, dest_addr, dest_seqno, DEV_NR(i).ipaddr); 00196 00197 00198 #ifdef OMNETPP 00199 rreq->ttl = ttl; 00200 aodv_socket_send((AODV_msg *) rreq, dest, RREQ_SIZE, 1, &DEV_NR(i),delay); 00201 totalRreqSend++; 00202 #else 00203 aodv_socket_send((AODV_msg *) rreq, dest, RREQ_SIZE, 1, &DEV_NR(i)); 00204 #endif 00205 } 00206 } 00207 00208 void NS_CLASS rreq_forward(RREQ * rreq, int size, int ttl) 00209 { 00210 struct in_addr dest, orig; 00211 int i; 00212 00213 dest.s_addr = ManetAddress(IPv4Address(AODV_BROADCAST)); 00214 orig.s_addr = rreq->orig_addr; 00215 00216 /* FORWARD the RREQ if the TTL allows it. */ 00217 DEBUG(LOG_INFO, 0, "forwarding RREQ src=%s, rreq_id=%lu", 00218 ip_to_str(orig), ntohl(rreq->rreq_id)); 00219 00220 /* Queue the received message in the send buffer */ 00221 #ifndef OMNETPP 00222 rreq = (RREQ *) aodv_socket_queue_msg((AODV_msg *) rreq, size); 00223 rreq->hcnt++; /* Increase hopcount to account for 00224 * intermediate route */ 00225 00226 /* Send out on all interfaces */ 00227 for (i = 0; i < MAX_NR_INTERFACES; i++) 00228 { 00229 if (!DEV_NR(i).enabled) 00230 continue; 00231 aodv_socket_send((AODV_msg *) rreq, dest, size, ttl, &DEV_NR(i)); 00232 #else 00233 rreq->hcnt++; /* Increase hopcount to account for 00234 * intermediate route */ 00235 if (this->isStaticNode()) 00236 rreq->hopfix++; 00237 /* Send out on all interfaces */ 00238 double delay = -1; 00239 if (par("EqualDelay")) 00240 delay = par("broadcastDelay"); 00241 00242 for (i = 0; i < MAX_NR_INTERFACES; i++) 00243 { 00244 if (!DEV_NR(i).enabled) 00245 continue; 00246 totalRreqSend++; 00247 RREQ * rreq_new = check_and_cast <RREQ*>(rreq->dup()); 00248 rreq_new->ttl=ttl; 00249 aodv_socket_send((AODV_msg *) rreq_new, dest, size, ttl, &DEV_NR(i),delay); 00250 #endif 00251 } 00252 } 00253 00254 void NS_CLASS rreq_process(RREQ * rreq, int rreqlen, struct in_addr ip_src, 00255 struct in_addr ip_dst, int ip_ttl, 00256 unsigned int ifindex) 00257 { 00258 00259 AODV_ext *ext=NULL; 00260 RREP *rrep = NULL; 00261 int rrep_size = RREP_SIZE; 00262 rt_table_t *rev_rt=NULL, *fwd_rt = NULL; 00263 u_int32_t rreq_orig_seqno, rreq_dest_seqno; 00264 u_int32_t rreq_id, rreq_new_hcnt, life; 00265 unsigned int extlen = 0; 00266 struct in_addr rreq_dest, rreq_orig; 00267 unsigned int ifaddr; 00268 uint32_t cost; 00269 uint8_t hopfix; 00270 00271 // BEGIN NA_SINKHOLE - sancale 00272 // Seqno sinkhole definition 00273 u_int32_t seqno_sinkhole; 00274 // END NA_SINKHOLE - sancale 00275 00276 ManetAddress aux; 00277 if (getAp(rreq->dest_addr, aux) && !isBroadcast(rreq->dest_addr)) 00278 { 00279 rreq_dest.s_addr = aux; 00280 } 00281 else 00282 rreq_dest.s_addr = rreq->dest_addr; 00283 00284 if (getAp(rreq->orig_addr, aux)) 00285 { 00286 rreq_orig.s_addr = aux; 00287 } 00288 else 00289 rreq_orig.s_addr = rreq->orig_addr; 00290 rreq_id = ntohl(rreq->rreq_id); 00291 rreq_dest_seqno = ntohl(rreq->dest_seqno); 00292 rreq_orig_seqno = ntohl(rreq->orig_seqno); 00293 rreq_new_hcnt = rreq->hcnt + 1; 00294 cost = rreq->cost; 00295 hopfix = rreq->hopfix; 00296 if (this->isStaticNode()) 00297 hopfix++; 00298 00299 00300 00301 /* Ignore RREQ's that originated from this node. Either we do this 00302 or we buffer our own sent RREQ's as we do with others we 00303 receive. */ 00304 ifaddr = DEV_IFINDEX(ifindex).ipaddr.s_addr.getIPv4().getInt(); 00305 #ifndef OMNETPP 00306 if (rreq_orig.s_addr == DEV_IFINDEX(ifindex).ipaddr.s_addr) 00307 return; 00308 #else 00309 if (isLocalAddress (rreq_orig.s_addr)) 00310 return; 00311 #endif 00312 00313 DEBUG(LOG_DEBUG, 0, "ip_src=%s rreq_orig=%s rreq_dest=%s\n", 00314 ip_to_str(ip_src), ip_to_str(rreq_orig), ip_to_str(rreq_dest)); 00315 #ifdef OMNETPP 00316 00317 totalRreqRec++; 00318 if (!ev.isDisabled()) 00319 ev.printf("ip_src=%s rreq_orig=%s rreq_dest=%s\n",ip_to_str(ip_src), 00320 ip_to_str(rreq_orig), ip_to_str(rreq_dest)); 00321 00322 00323 // BEGIN NA_SINKHOLE - sancale 00324 // If sinkhole does not know the route, update seqno to seqno_sinkhole and hop_count to 1. 00325 if (sinkholeAttackIsActive) { 00326 if ((sinkOnlyWhenRouteInTable == false) and (uniform(0, 1) < sinkholeAttackProbability)) { 00327 u_int32_t seqno_added = seqnoAdded->doubleValue(); 00328 int num_hops = numHops; 00329 seqno_sinkhole = rreq_dest_seqno + seqno_added; 00330 EV << "Sinkhole does not know the route but sends false RREP with seqnoAdded = " << seqno_added << " and numHops = " << num_hops << ".\n"; 00331 //IPv4Address node_address = IPvXAddressResolver().resolve("attacker").get4(); 00332 //EV << simTime() << "s: " << rreq->getName() << " received in " << node_address << " (" << getParentModule()->getFullName() << ") originated from " << ip_to_str(rreq_orig) << "\n"; 00333 00334 /* The node always creates or updates a REVERSE ROUTE entry to the source of the RREQ. */ 00335 rev_rt = rt_table_find(rreq_orig); 00336 /* Calculate the extended minimal life time. */ 00337 life = PATH_DISCOVERY_TIME - 2 * rreq_new_hcnt * NODE_TRAVERSAL_TIME; 00338 if (rev_rt == NULL) { 00339 DEBUG(LOG_DEBUG, 0, "Creating REVERSE route entry, RREQ orig: %s", ip_to_str(rreq_orig)); 00340 rev_rt = rt_table_insert(rreq_orig, ip_src, rreq_new_hcnt, rreq_orig_seqno, life, VALID, 0, ifindex,cost,hopfix); 00341 } else { 00342 if (!useHover && (rev_rt->dest_seqno == 0 || (int32_t) rreq_orig_seqno > (int32_t) rev_rt->dest_seqno || 00343 (rreq_orig_seqno == rev_rt->dest_seqno && (rev_rt->state == INVALID || rreq_new_hcnt < rev_rt->hcnt)))) { 00344 rev_rt = rt_table_update(rev_rt, ip_src, rreq_new_hcnt, rreq_orig_seqno, life, VALID, rev_rt->flags,ifindex,cost,hopfix); 00345 } else if (useHover && (rev_rt->dest_seqno == 0 || (int32_t) rreq_orig_seqno > (int32_t) rev_rt->dest_seqno || 00346 (rreq_orig_seqno == rev_rt->dest_seqno && (rev_rt->state == INVALID || cost < rev_rt->cost)))) { 00347 rev_rt = rt_table_update(rev_rt, ip_src, rreq_new_hcnt, rreq_orig_seqno, life, VALID, rev_rt->flags,ifindex,cost,hopfix); 00348 } 00349 } 00350 /**** END updating/creating REVERSE route ****/ 00351 00352 /* Set the destination IP address in RREP (dest_addr) to the IP address of the destination for which a route is supplied (rreq_dest in RREQ). 00353 * Set the originator IP address in RREP (orig_addr) to the IP address of the node which originated the RREQ for which the route is supplied (rreq_orig in RREQ). 00354 */ 00355 rrep = rrep_create(0, 0, num_hops, rreq_dest, seqno_sinkhole, rreq_orig, ACTIVE_ROUTE_TIMEOUT); 00356 rrep_send(rrep, rev_rt, NULL, RREP_SIZE); 00357 return; 00358 } 00359 } 00360 // END NA_SINKHOLE - sancale 00361 00362 #endif 00363 00364 if (rreqlen < (int) RREQ_SIZE) 00365 { 00366 alog(LOG_WARNING, 0, 00367 __FUNCTION__, "IP data field too short (%u bytes)" 00368 "from %s to %s", rreqlen, ip_to_str(ip_src), ip_to_str(ip_dst)); 00369 return; 00370 } 00371 00372 /* Check if the previous hop of the RREQ is in the blacklist set. If 00373 it is, then ignore the RREQ. */ 00374 if (rreq_blacklist_find(ip_src)) 00375 { 00376 DEBUG(LOG_DEBUG, 0, "prev hop of RREQ blacklisted, ignoring!"); 00377 #ifdef OMNETPP 00378 EV << "prev hop of RREQ blacklisted, ignoring!"; 00379 #endif 00380 return; 00381 } 00382 00383 /* Ignore already processed RREQs. */ 00384 if (rreq_record_find(rreq_orig, rreq_id)) 00385 { 00386 life = PATH_DISCOVERY_TIME - 2 * rreq_new_hcnt * NODE_TRAVERSAL_TIME; 00387 #ifdef OMNETPP 00388 if (isBroadcast(rreq_dest.s_addr)) 00389 { 00390 rev_rt = rt_table_find(rreq_orig); 00391 if (rev_rt == NULL) 00392 { 00393 rev_rt = rt_table_insert(rreq_orig, ip_src, rreq_new_hcnt, rreq_orig_seqno, life, VALID, 0, ifindex,cost,hopfix); 00394 // opp_error("reverse route NULL with RREQ in the processed table" ); 00395 } 00396 if (rev_rt->dest_seqno != 0) 00397 { 00398 if ((int32_t) rreq_orig_seqno < (int32_t) rev_rt->dest_seqno) 00399 return; 00400 if (!useHover && (rreq_orig_seqno == rev_rt->dest_seqno && 00401 (rev_rt->state != INVALID && rreq_new_hcnt >= rev_rt->hcnt))) 00402 return; 00403 if (useHover && (rreq_orig_seqno == rev_rt->dest_seqno && 00404 (rev_rt->state != INVALID && cost >= rev_rt->cost))) 00405 return; 00406 } 00407 } 00408 else 00409 #endif 00410 { 00411 rev_rt = rt_table_find(rreq_orig); 00412 if (rev_rt == NULL) 00413 { 00414 rev_rt = rt_table_insert(rreq_orig, ip_src, rreq_new_hcnt,rreq_orig_seqno, life, VALID, 0, ifindex,cost,hopfix); 00415 // opp_error("reverse route NULL with RREQ in the processed table" ); 00416 } 00417 if (useHover && (rev_rt->dest_seqno == 0 || 00418 (int32_t) rreq_orig_seqno > (int32_t) rev_rt->dest_seqno || 00419 (rreq_orig_seqno == rev_rt->dest_seqno && 00420 (rev_rt->state == INVALID || cost < rev_rt->cost)))) 00421 { 00422 life = PATH_DISCOVERY_TIME - 2 * rreq_new_hcnt * NODE_TRAVERSAL_TIME; 00423 rev_rt = rt_table_update(rev_rt, ip_src, rreq_new_hcnt, 00424 rreq_orig_seqno, life, VALID, 00425 rev_rt->flags,ifindex,cost,hopfix); 00426 } 00427 return; 00428 } 00429 } 00430 00431 /* Now buffer this RREQ so that we don't process a similar RREQ we 00432 get within PATH_DISCOVERY_TIME. */ 00433 rreq_record_insert(rreq_orig, rreq_id); 00434 00435 /* Determine whether there are any RREQ extensions */ 00436 00437 00438 #ifndef OMNETPP 00439 ext = (AODV_ext *) ((char *) rreq + RREQ_SIZE); 00440 while ((rreqlen - extlen) > RREQ_SIZE) 00441 { 00442 #else 00443 ext = rreq->getFirstExtension(); 00444 for (int i=0; i<rreq->getNumExtension (); i++) 00445 { 00446 #endif 00447 switch (ext->type) 00448 { 00449 case RREQ_EXT: 00450 DEBUG(LOG_INFO, 0, "RREQ include EXTENSION"); 00451 /* Do something here */ 00452 break; 00453 default: 00454 alog(LOG_WARNING, 0, __FUNCTION__, "Unknown extension type %d", 00455 ext->type); 00456 break; 00457 } 00458 extlen += AODV_EXT_SIZE(ext); 00459 ext = AODV_EXT_NEXT(ext); 00460 } 00461 #ifdef DEBUG_OUTPUT 00462 log_pkt_fields((AODV_msg *) rreq); 00463 #endif 00464 00465 /* The node always creates or updates a REVERSE ROUTE entry to the 00466 source of the RREQ. */ 00467 rev_rt = rt_table_find(rreq_orig); 00468 00469 /* Calculate the extended minimal life time. */ 00470 life = PATH_DISCOVERY_TIME - 2 * rreq_new_hcnt * NODE_TRAVERSAL_TIME; 00471 00472 if (rev_rt == NULL) 00473 { 00474 DEBUG(LOG_DEBUG, 0, "Creating REVERSE route entry, RREQ orig: %s", 00475 ip_to_str(rreq_orig)); 00476 00477 rev_rt = rt_table_insert(rreq_orig, ip_src, rreq_new_hcnt, 00478 rreq_orig_seqno, life, VALID, 0, ifindex,cost,hopfix); 00479 } 00480 else 00481 { 00482 if (!useHover && (rev_rt->dest_seqno == 0 || 00483 (int32_t) rreq_orig_seqno > (int32_t) rev_rt->dest_seqno || 00484 (rreq_orig_seqno == rev_rt->dest_seqno && 00485 (rev_rt->state == INVALID || rreq_new_hcnt < rev_rt->hcnt)))) 00486 { 00487 rev_rt = rt_table_update(rev_rt, ip_src, rreq_new_hcnt, 00488 rreq_orig_seqno, life, VALID, 00489 rev_rt->flags,ifindex,cost,hopfix); 00490 } 00491 00492 00493 else if (useHover && (rev_rt->dest_seqno == 0 || 00494 (int32_t) rreq_orig_seqno > (int32_t) rev_rt->dest_seqno || 00495 (rreq_orig_seqno == rev_rt->dest_seqno && 00496 (rev_rt->state == INVALID || cost < rev_rt->cost)))) 00497 { 00498 rev_rt = rt_table_update(rev_rt, ip_src, rreq_new_hcnt, 00499 rreq_orig_seqno, life, VALID, 00500 rev_rt->flags,ifindex,cost,hopfix); 00501 } 00502 00503 #ifdef DISABLED 00504 /* This is a out of draft modification of AODV-UU to prevent 00505 nodes from creating routing entries to themselves during 00506 the RREP phase. We simple drop the RREQ if there is a 00507 missmatch between the reverse path on the node and the one 00508 suggested by the RREQ. */ 00509 00510 else if (rev_rt->next_hop.s_addr != ip_src.s_addr) 00511 { 00512 DEBUG(LOG_DEBUG, 0, "Dropping RREQ due to reverse route mismatch!"); 00513 return; 00514 } 00515 #endif 00516 } 00517 /**** END updating/creating REVERSE route ****/ 00518 00519 #ifdef CONFIG_GATEWAY 00520 /* This is a gateway */ 00521 if (internet_gw_mode) 00522 { 00523 /* Subnet locality decision */ 00524 switch (locality(rreq_dest, ifindex)) 00525 { 00526 case HOST_ADHOC: 00527 break; 00528 case HOST_INET: 00529 /* We must increase the gw's sequence number before sending a RREP, 00530 * otherwise intermediate nodes will not forward the RREP. */ 00531 seqno_incr(this_host.seqno); 00532 rrep = rrep_create(0, 0, 0, DEV_IFINDEX(rev_rt->ifindex).ipaddr, 00533 this_host.seqno, rev_rt->dest_addr, 00534 ACTIVE_ROUTE_TIMEOUT); 00535 00536 ext = rrep_add_ext(rrep, RREP_INET_DEST_EXT, rrep_size, 00537 sizeof(struct in_addr), (char *) &rreq_dest); 00538 00539 rrep_size += AODV_EXT_SIZE(ext); 00540 00541 DEBUG(LOG_DEBUG, 0, 00542 "Responding for INTERNET dest: %s rrep_size=%d", 00543 ip_to_str(rreq_dest), rrep_size); 00544 00545 rrep_send(rrep, rev_rt, NULL, rrep_size); 00546 00547 return; 00548 00549 case HOST_UNKNOWN: 00550 default: 00551 DEBUG(LOG_DEBUG, 0, "GW: Destination unkown"); 00552 } 00553 } 00554 #endif 00555 00556 #ifdef OMNETPP 00557 if (getIsGateway()) 00558 { 00559 /* Subnet locality decision */ 00560 // search address 00561 if (isAddressInProxyList(rreq_dest.s_addr)) 00562 { 00563 /* We must increase the gw's sequence number before sending a RREP, 00564 * otherwise intermediate nodes will not forward the RREP. */ 00565 seqno_incr(this_host.seqno); 00566 rrep = rrep_create(0, 0, 0, DEV_IFINDEX(rev_rt->ifindex).ipaddr, 00567 this_host.seqno, rev_rt->dest_addr, 00568 ACTIVE_ROUTE_TIMEOUT); 00569 00570 ext = rrep_add_ext(rrep, RREP_INET_DEST_EXT, rrep_size, 00571 sizeof(struct in_addr), (char *) &rreq_dest); 00572 00573 rrep_size += AODV_EXT_SIZE(ext); 00574 00575 00576 DEBUG(LOG_DEBUG, 0, 00577 "Responding for INTERNET dest: %s rrep_size=%d", 00578 ip_to_str(rreq_dest), rrep_size); 00579 00580 rrep_send(rrep, rev_rt, NULL, rrep_size); 00581 00582 return; 00583 00584 } 00585 } 00586 #endif 00587 /* Are we the destination of the RREQ?, if so we should immediately send a 00588 RREP.. */ 00589 #ifndef OMNETPP 00590 if (rreq_dest.s_addr == DEV_IFINDEX(ifindex).ipaddr.s_addr) 00591 { 00592 #else 00593 if (isLocalAddress (rreq_dest.s_addr)) 00594 { 00595 #endif 00596 00597 /* WE are the RREQ DESTINATION. Update the node's own 00598 sequence number to the maximum of the current seqno and the 00599 one in the RREQ. */ 00600 if (rreq_dest_seqno != 0) 00601 { 00602 if ((int32_t) this_host.seqno < (int32_t) rreq_dest_seqno) 00603 this_host.seqno = rreq_dest_seqno; 00604 else if (this_host.seqno == rreq_dest_seqno) 00605 seqno_incr(this_host.seqno); 00606 } 00607 rrep = rrep_create(0, 0, 0, DEV_IFINDEX(rev_rt->ifindex).ipaddr, 00608 this_host.seqno, rev_rt->dest_addr, 00609 MY_ROUTE_TIMEOUT); 00610 #ifdef OMNETPP 00611 EV << " create a rrep" << ip_to_str(DEV_IFINDEX(rev_rt->ifindex).ipaddr) << "seq n" << this_host.seqno << " to " << ip_to_str(rev_rt->dest_addr); 00612 #endif 00613 00614 rrep_send(rrep, rev_rt, NULL, RREP_SIZE); 00615 00616 } 00617 else if (isBroadcast (rreq_dest.s_addr)) 00618 { 00619 if(!rreq->d) 00620 return; 00621 if (!propagateProactive) 00622 return; 00623 00624 /* WE are the RREQ DESTINATION. Update the node's own 00625 sequence number to the maximum of the current seqno and the 00626 one in the RREQ. */ 00627 seqno_incr(this_host.seqno); 00628 rrep = rrep_create(0, 0, 0, DEV_IFINDEX(rev_rt->ifindex).ipaddr,this_host.seqno, rev_rt->dest_addr, MY_ROUTE_TIMEOUT); 00629 EV << " create a rrep" << ip_to_str(DEV_IFINDEX(rev_rt->ifindex).ipaddr) << "seq n" << this_host.seqno << " to " << ip_to_str(rev_rt->dest_addr); 00630 rrep_send(rrep, rev_rt, NULL, RREP_SIZE); 00631 if (ip_ttl > 0) 00632 { 00633 rreq_forward(rreq, rreqlen, ip_ttl); // the ttl is decremented for ip layer 00634 } 00635 else 00636 { 00637 DEBUG(LOG_DEBUG, 0, "RREQ not forwarded - ttl=0"); 00638 EV << "RREQ not forwarded - ttl=0"; 00639 } 00640 return; 00641 } 00642 else 00643 { 00644 /* We are an INTERMEDIATE node. - check if we have an active 00645 * route entry */ 00646 00647 fwd_rt = rt_table_find(rreq_dest); 00648 00649 // BEGIN NA_SINKHOLE - sancale 00650 // If sinkhole knows the route, update seqno to seqno_sinkhole and hop_count to 1. 00651 // If route exist and is valid. We do not care about the "only destination" flag in the RREQ. 00652 if (fwd_rt && (fwd_rt->state == VALID || fwd_rt->state == IMMORTAL)){ 00653 /* Respond only if the sequence number is fresh enough... */ 00654 if ((fwd_rt->dest_seqno != 0 && (int32_t) fwd_rt->dest_seqno >= (int32_t) rreq_dest_seqno && 00655 (fwd_rt->hcnt>HCNT_LIMIT))|| fwd_rt->state==IMMORTAL) { 00656 00657 if (sinkholeAttackIsActive) { 00658 if ((sinkOnlyWhenRouteInTable == true) and (uniform(0,1) < sinkholeAttackProbability)) { 00659 00660 struct timeval now; 00661 u_int32_t lifetime; 00662 gettimeofday(&now, NULL); 00663 00664 if (fwd_rt->state == IMMORTAL) 00665 lifetime = 10000; 00666 else { 00667 #ifdef AODV_USE_STL 00668 double val = SIMTIME_DBL(fwd_rt->rt_timer.timeout - simTime()); 00669 lifetime = (val * 1000.0); 00670 #else 00671 lifetime = timeval_diff(&fwd_rt->rt_timer.timeout, &now); 00672 #endif 00673 } 00674 u_int32_t seqno_added = seqnoAdded->doubleValue(); 00675 int num_hops = numHops; 00676 seqno_sinkhole = rreq_dest_seqno + seqno_added; 00677 rrep = rrep_create(0, 0, num_hops, fwd_rt->dest_addr, seqno_sinkhole, rev_rt->dest_addr, lifetime); 00678 rrep_send(rrep, rev_rt, fwd_rt, rrep_size); 00679 EV << "Sinkhole knows the route and sends false RREP with seqnoAdded = " << seqno_added << " and numHops = " << num_hops << ".\n"; 00680 return; 00681 } 00682 } 00683 } 00684 } 00685 // END NA_SINKHOLE - sancale 00686 00687 if (fwd_rt && (fwd_rt->state == VALID || fwd_rt->state == IMMORTAL) && !rreq->d) 00688 { 00689 struct timeval now; 00690 u_int32_t lifetime; 00691 00692 /* GENERATE RREP, i.e we have an ACTIVE route entry that is fresh 00693 enough (our destination sequence number for that route is 00694 larger than the one in the RREQ). */ 00695 00696 gettimeofday(&now, NULL); 00697 #ifdef CONFIG_GATEWAY_DISABLED 00698 if (fwd_rt->flags & RT_INET_DEST) 00699 { 00700 rt_table_t *gw_rt; 00701 /* This node knows that this is a rreq for an Internet 00702 * destination and it has a valid route to the gateway */ 00703 00704 goto forward; // DISABLED 00705 00706 gw_rt = rt_table_find(fwd_rt->next_hop); 00707 00708 if (!gw_rt || gw_rt->state == INVALID) 00709 goto forward; 00710 00711 lifetime = timeval_diff(&gw_rt->rt_timer.timeout, &now); 00712 00713 rrep = rrep_create(0, 0, gw_rt->hcnt, gw_rt->dest_addr, 00714 gw_rt->dest_seqno, rev_rt->dest_addr, 00715 lifetime); 00716 00717 ext = rrep_add_ext(rrep, RREP_INET_DEST_EXT, rrep_size, 00718 sizeof(struct in_addr), (char *) &rreq_dest); 00719 00720 rrep_size += AODV_EXT_SIZE(ext); 00721 00722 DEBUG(LOG_DEBUG, 0, 00723 "Intermediate node response for INTERNET dest: %s rrep_size=%d", 00724 ip_to_str(rreq_dest), rrep_size); 00725 00726 rrep_send(rrep, rev_rt, gw_rt, rrep_size); 00727 return; 00728 } 00729 #endif /* CONFIG_GATEWAY_DISABLED */ 00730 00731 /* Respond only if the sequence number is fresh enough... */ 00732 // if ((fwd_rt->dest_seqno != 0 && 00733 // (int32_t) fwd_rt->dest_seqno >= (int32_t) rreq_dest_seqno && 00734 // (fwd_rt->hcnt>HCNT_LIMIT || (fwd_rt->hcnt==HCNT_LIMIT && uniform(0, 1)>0.8 ))) || fwd_rt->state==IMMORTAL) { 00735 if ((fwd_rt->dest_seqno != 0 && 00736 (int32_t) fwd_rt->dest_seqno >= (int32_t) rreq_dest_seqno && 00737 (fwd_rt->hcnt>HCNT_LIMIT))|| fwd_rt->state==IMMORTAL) 00738 { 00739 // if (fwd_rt->dest_seqno != 0 && 00740 // (int32_t) fwd_rt->dest_seqno >= (int32_t) rreq_dest_seqno) { 00741 #ifdef AODV_USE_STL 00742 if (fwd_rt->state==IMMORTAL) 00743 lifetime = 10000; 00744 else 00745 { 00746 double val = SIMTIME_DBL(fwd_rt->rt_timer.timeout - simTime()); 00747 lifetime = (val * 1000.0); 00748 } 00749 #else 00750 if (fwd_rt->state==IMMORTAL) 00751 lifetime = 10000; 00752 else 00753 lifetime = timeval_diff(&fwd_rt->rt_timer.timeout, &now); 00754 #endif 00755 rrep = rrep_create(0, 0, fwd_rt->hcnt, fwd_rt->dest_addr, 00756 fwd_rt->dest_seqno, rev_rt->dest_addr, 00757 lifetime); 00758 rrep_send(rrep, rev_rt, fwd_rt, rrep_size); 00759 /* If the GRATUITOUS flag is set, we must also unicast a 00760 gratuitous RREP to the destination. */ 00761 if (rreq->g) 00762 { 00763 rrep = rrep_create(0, 0, rev_rt->hcnt, rev_rt->dest_addr, 00764 rev_rt->dest_seqno, fwd_rt->dest_addr, 00765 lifetime); 00766 rrep_send(rrep, fwd_rt, rev_rt, RREP_SIZE); 00767 DEBUG(LOG_INFO, 0, "Sending G-RREP to %s with rte to %s", 00768 ip_to_str(rreq_dest), ip_to_str(rreq_orig)); 00769 } 00770 return; 00771 } 00772 /* 00773 else 00774 { 00775 goto forward; 00776 } 00777 // If the GRATUITOUS flag is set, we must also unicast a 00778 // gratuitous RREP to the destination. 00779 if (rreq->g) 00780 { 00781 rrep = rrep_create(0, 0, rev_rt->hcnt, rev_rt->dest_addr, 00782 rev_rt->dest_seqno, fwd_rt->dest_addr, 00783 lifetime); 00784 00785 rrep_send(rrep, fwd_rt, rev_rt, RREP_SIZE); 00786 00787 DEBUG(LOG_INFO, 0, "Sending G-RREP to %s with rte to %s", 00788 ip_to_str(rreq_dest), ip_to_str(rreq_orig)); 00789 } 00790 return; 00791 */ 00792 } 00793 forward: 00794 #ifndef OMNETPP 00795 if (ip_ttl > 1) 00796 #else 00797 if (ip_ttl > 0) 00798 #endif 00799 { 00800 /* Update the sequence number in case the maintained one is larger */ 00801 if (fwd_rt && (fwd_rt->state == VALID || fwd_rt->state == IMMORTAL) && !rreq->d&& 0!=HCNT_LIMIT) 00802 { 00803 if (fwd_rt->dest_seqno != 0 && 00804 (int32_t) fwd_rt->dest_seqno >= (int32_t) rreq_dest_seqno && fwd_rt->hcnt==HCNT_LIMIT) 00805 ip_ttl = HCNT_LIMIT; 00806 } 00807 if (fwd_rt && !(fwd_rt->flags & RT_INET_DEST) && 00808 (int32_t) fwd_rt->dest_seqno > (int32_t) rreq_dest_seqno) 00809 rreq->dest_seqno = htonl(fwd_rt->dest_seqno); 00810 #ifndef OMNETPP 00811 rreq_forward(rreq, rreqlen, --ip_ttl); 00812 #else 00813 rreq_forward(rreq, rreqlen, ip_ttl); // the ttl is decremented for ip layer 00814 #endif 00815 } 00816 else 00817 { 00818 DEBUG(LOG_DEBUG, 0, "RREQ not forwarded - ttl=0"); 00819 #ifdef OMNETPP 00820 EV << "RREQ not forwarded - ttl=0"; 00821 #endif 00822 } 00823 } 00824 } 00825 00826 /* Perform route discovery for a unicast destination */ 00827 00828 void NS_CLASS rreq_route_discovery(struct in_addr dest_addr, u_int8_t flags, 00829 struct ip_data *ipd) 00830 { 00831 struct timeval now; 00832 rt_table_t *rt; 00833 seek_list_t *seek_entry; 00834 u_int32_t dest_seqno; 00835 int ttl; 00836 #define TTL_VALUE ttl 00837 00838 gettimeofday(&now, NULL); 00839 00840 if (seek_list_find(dest_addr)) 00841 return; 00842 00843 /* If we already have a route entry, we use information from it. */ 00844 rt = rt_table_find(dest_addr); 00845 00846 ttl = NET_DIAMETER; /* This is the TTL if we don't use expanding 00847 ring search */ 00848 if (!rt) 00849 { 00850 dest_seqno = 0; 00851 00852 if (expanding_ring_search) 00853 ttl = TTL_START; 00854 00855 } 00856 else 00857 { 00858 dest_seqno = rt->dest_seqno; 00859 00860 if (expanding_ring_search) 00861 { 00862 ttl = rt->hcnt + TTL_INCREMENT; 00863 } 00864 00865 /* if (rt->flags & RT_INET_DEST) */ 00866 /* flags |= RREQ_DEST_ONLY; */ 00867 00868 /* A routing table entry waiting for a RREP should not be expunged 00869 before 2 * NET_TRAVERSAL_TIME... */ 00870 #ifdef AODV_USE_STL 00871 if ((rt->rt_timer.timeout - simTime()) < (2 * NET_TRAVERSAL_TIME)) 00872 rt_table_update_timeout(rt, 2 * NET_TRAVERSAL_TIME); 00873 #else 00874 if (timeval_diff(&rt->rt_timer.timeout, &now) < 00875 (2 * NET_TRAVERSAL_TIME)) 00876 rt_table_update_timeout(rt, 2 * NET_TRAVERSAL_TIME); 00877 #endif 00878 } 00879 00880 rreq_send(dest_addr, dest_seqno, ttl, flags); 00881 00882 /* Remember that we are seeking this destination */ 00883 seek_entry = seek_list_insert(dest_addr, dest_seqno, ttl, flags, ipd); 00884 00885 /* Set a timer for this RREQ */ 00886 if (expanding_ring_search) 00887 timer_set_timeout(&seek_entry->seek_timer, RING_TRAVERSAL_TIME); 00888 else 00889 timer_set_timeout(&seek_entry->seek_timer, NET_TRAVERSAL_TIME); 00890 00891 DEBUG(LOG_DEBUG, 0, "Seeking %s ttl=%d", ip_to_str(dest_addr), ttl); 00892 00893 return; 00894 } 00895 00896 /* Local repair is very similar to route discovery... */ 00897 void NS_CLASS rreq_local_repair(rt_table_t * rt, struct in_addr src_addr, 00898 struct ip_data *ipd) 00899 { 00900 struct timeval now; 00901 seek_list_t *seek_entry; 00902 rt_table_t *src_entry; 00903 int ttl; 00904 u_int8_t flags = 0; 00905 00906 if (!rt) 00907 return; 00908 00909 if (seek_list_find(rt->dest_addr)) 00910 return; 00911 00912 if (!(rt->flags & RT_REPAIR)) 00913 return; 00914 00915 gettimeofday(&now, NULL); 00916 00917 DEBUG(LOG_DEBUG, 0, "REPAIRING route to %s", ip_to_str(rt->dest_addr)); 00918 00919 /* Caclulate the initial ttl to use for the RREQ. MIN_REPAIR_TTL 00920 mentioned in the draft is the last known hop count to the 00921 destination. */ 00922 00923 src_entry = rt_table_find(src_addr); 00924 00925 if (src_entry) 00926 ttl = max((int)rt->hcnt, (int)(0.5 * src_entry->hcnt)) + LOCAL_ADD_TTL; 00927 else 00928 ttl = rt->hcnt + LOCAL_ADD_TTL; 00929 00930 DEBUG(LOG_DEBUG, 0, "%s, rreq ttl=%d, dest_hcnt=%d", 00931 ip_to_str(rt->dest_addr), ttl, rt->hcnt); 00932 00933 /* Reset the timeout handler, was probably previously 00934 local_repair_timeout */ 00935 rt->rt_timer.handler = &NS_CLASS route_expire_timeout; 00936 00937 #ifdef AODV_USE_STL 00938 if ((rt->rt_timer.timeout -simTime()) < (2 * NET_TRAVERSAL_TIME)) 00939 rt_table_update_timeout(rt, 2 * NET_TRAVERSAL_TIME); 00940 #else 00941 if (timeval_diff(&rt->rt_timer.timeout, &now) < (2 * NET_TRAVERSAL_TIME)) 00942 rt_table_update_timeout(rt, 2 * NET_TRAVERSAL_TIME); 00943 #endif 00944 00945 rreq_send(rt->dest_addr, rt->dest_seqno, ttl, flags); 00946 00947 /* Remember that we are seeking this destination and setup the 00948 timers */ 00949 seek_entry = seek_list_insert(rt->dest_addr, rt->dest_seqno, 00950 ttl, flags, ipd); 00951 00952 if (expanding_ring_search) 00953 timer_set_timeout(&seek_entry->seek_timer, 00954 2 * ttl * NODE_TRAVERSAL_TIME); 00955 else 00956 timer_set_timeout(&seek_entry->seek_timer, NET_TRAVERSAL_TIME); 00957 00958 DEBUG(LOG_DEBUG, 0, "Seeking %s ttl=%d", ip_to_str(rt->dest_addr), ttl); 00959 00960 return; 00961 } 00962 00963 // proactive RREQ 00964 void NS_CLASS rreq_proactive (void *arg) 00965 { 00966 struct in_addr dest; 00967 if (!isRoot) 00968 return; 00969 if (this->isInMacLayer()) 00970 dest.s_addr= ManetAddress(MACAddress::BROADCAST_ADDRESS); 00971 else 00972 dest.s_addr= ManetAddress(IPv4Address::ALLONES_ADDRESS); 00973 rreq_send(dest,0,NET_DIAMETER, RREQ_DEST_ONLY); 00974 timer_set_timeout(&proactive_rreq_timer, proactive_rreq_timeout); 00975 } 00976 00977 #ifndef AODV_USE_STL 00978 NS_STATIC struct rreq_record *NS_CLASS rreq_record_insert(struct in_addr orig_addr, 00979 u_int32_t rreq_id) 00980 { 00981 struct rreq_record *rec; 00982 00983 /* First check if this rreq packet is already buffered */ 00984 rec = rreq_record_find(orig_addr, rreq_id); 00985 00986 /* If already buffered, should we update the timer??? */ 00987 if (rec) 00988 return rec; 00989 00990 if ((rec = 00991 (struct rreq_record *) malloc(sizeof(struct rreq_record))) == NULL) 00992 { 00993 fprintf(stderr, "Malloc failed!!!\n"); 00994 exit(-1); 00995 } 00996 rec->orig_addr = orig_addr; 00997 rec->rreq_id = rreq_id; 00998 00999 timer_init(&rec->rec_timer, &NS_CLASS rreq_record_timeout, rec); 01000 01001 list_add(&rreq_records, &rec->l); 01002 01003 DEBUG(LOG_INFO, 0, "Buffering RREQ %s rreq_id=%lu time=%u", 01004 ip_to_str(orig_addr), rreq_id, PATH_DISCOVERY_TIME); 01005 01006 timer_set_timeout(&rec->rec_timer, PATH_DISCOVERY_TIME); 01007 return rec; 01008 } 01009 01010 NS_STATIC struct rreq_record *NS_CLASS rreq_record_find(struct in_addr orig_addr, 01011 u_int32_t rreq_id) 01012 { 01013 list_t *pos; 01014 01015 list_foreach(pos, &rreq_records) 01016 { 01017 struct rreq_record *rec = (struct rreq_record *) pos; 01018 if (rec->orig_addr.s_addr == orig_addr.s_addr && 01019 (rec->rreq_id == rreq_id)) 01020 return rec; 01021 } 01022 return NULL; 01023 } 01024 01025 void NS_CLASS rreq_record_timeout(void *arg) 01026 { 01027 struct rreq_record *rec = (struct rreq_record *) arg; 01028 01029 list_detach(&rec->l); 01030 free(rec); 01031 } 01032 01033 01034 struct blacklist *NS_CLASS rreq_blacklist_insert(struct in_addr dest_addr) 01035 { 01036 01037 struct blacklist *bl; 01038 01039 /* First check if this rreq packet is already buffered */ 01040 bl = rreq_blacklist_find(dest_addr); 01041 01042 /* If already buffered, should we update the timer??? */ 01043 if (bl) 01044 return bl; 01045 01046 if ((bl = (struct blacklist *) malloc(sizeof(struct blacklist))) == NULL) 01047 { 01048 fprintf(stderr, "Malloc failed!!!\n"); 01049 exit(-1); 01050 } 01051 bl->dest_addr.s_addr = dest_addr.s_addr; 01052 01053 timer_init(&bl->bl_timer, &NS_CLASS rreq_blacklist_timeout, bl); 01054 01055 list_add(&rreq_blacklist, &bl->l); 01056 01057 timer_set_timeout(&bl->bl_timer, BLACKLIST_TIMEOUT); 01058 return bl; 01059 } 01060 01061 01062 struct blacklist *NS_CLASS rreq_blacklist_find(struct in_addr dest_addr) 01063 { 01064 list_t *pos; 01065 01066 list_foreach(pos, &rreq_blacklist) 01067 { 01068 struct blacklist *bl = (struct blacklist *) pos; 01069 01070 if (bl->dest_addr.s_addr == dest_addr.s_addr) 01071 return bl; 01072 } 01073 return NULL; 01074 } 01075 01076 void NS_CLASS rreq_blacklist_timeout(void *arg) 01077 { 01078 01079 struct blacklist *bl = (struct blacklist *) arg; 01080 01081 list_detach(&bl->l); 01082 free(bl); 01083 } 01084 #else 01085 NS_STATIC struct rreq_record *NS_CLASS rreq_record_insert(struct in_addr orig_addr, 01086 u_int32_t rreq_id) 01087 { 01088 struct rreq_record *rec; 01089 01090 /* First check if this rreq packet is already buffered */ 01091 rec = rreq_record_find(orig_addr, rreq_id); 01092 01093 /* If already buffered, should we update the timer??? */ 01094 if (rec) 01095 return rec; 01096 01097 if ((rec = 01098 (struct rreq_record *) malloc(sizeof(struct rreq_record))) == NULL) 01099 { 01100 fprintf(stderr, "Malloc failed!!!\n"); 01101 exit(-1); 01102 } 01103 rec->orig_addr = orig_addr; 01104 rec->rreq_id = rreq_id; 01105 01106 timer_init(&rec->rec_timer, &NS_CLASS rreq_record_timeout, rec); 01107 rreq_records.push_back(rec); 01108 01109 01110 DEBUG(LOG_INFO, 0, "Buffering RREQ %s rreq_id=%lu time=%u", 01111 ip_to_str(orig_addr), rreq_id, PATH_DISCOVERY_TIME); 01112 01113 timer_set_timeout(&rec->rec_timer, PATH_DISCOVERY_TIME); 01114 return rec; 01115 } 01116 01117 NS_STATIC struct rreq_record *NS_CLASS rreq_record_find(struct in_addr orig_addr, 01118 u_int32_t rreq_id) 01119 { 01120 for (unsigned int i = 0 ; i < rreq_records.size();i++) 01121 { 01122 struct rreq_record *rec = rreq_records[i]; 01123 if (rec->orig_addr.s_addr == orig_addr.s_addr && 01124 (rec->rreq_id == rreq_id)) 01125 return rec; 01126 } 01127 return NULL; 01128 } 01129 01130 void NS_CLASS rreq_record_timeout(void *arg) 01131 { 01132 struct rreq_record *rec = (struct rreq_record *) arg; 01133 for (RreqRecords::iterator it = rreq_records.begin();it!=rreq_records.end();it++) 01134 { 01135 struct rreq_record *recAux = *it; 01136 if (rec == recAux) 01137 { 01138 rreq_records.erase(it); 01139 break; 01140 } 01141 } 01142 free(rec); 01143 } 01144 01145 01146 struct blacklist *NS_CLASS rreq_blacklist_insert(struct in_addr dest_addr) 01147 { 01148 01149 struct blacklist *bl; 01150 01151 /* First check if this rreq packet is already buffered */ 01152 bl = rreq_blacklist_find(dest_addr); 01153 01154 /* If already buffered, should we update the timer??? */ 01155 if (bl) 01156 return bl; 01157 01158 if ((bl = (struct blacklist *) malloc(sizeof(struct blacklist))) == NULL) 01159 { 01160 fprintf(stderr, "Malloc failed!!!\n"); 01161 exit(-1); 01162 } 01163 bl->dest_addr.s_addr = dest_addr.s_addr; 01164 01165 timer_init(&bl->bl_timer, &NS_CLASS rreq_blacklist_timeout, bl); 01166 rreq_blacklist.insert(std::make_pair(dest_addr.s_addr,bl)); 01167 01168 timer_set_timeout(&bl->bl_timer, BLACKLIST_TIMEOUT); 01169 return bl; 01170 } 01171 01172 01173 struct blacklist *NS_CLASS rreq_blacklist_find(struct in_addr dest_addr) 01174 { 01175 RreqBlacklist::iterator it = rreq_blacklist.find(dest_addr.s_addr); 01176 if (it != rreq_blacklist.end()) 01177 return it->second; 01178 return NULL; 01179 } 01180 01181 void NS_CLASS rreq_blacklist_timeout(void *arg) 01182 { 01183 struct blacklist *bl = (struct blacklist *)arg; 01184 for (RreqBlacklist::iterator it = rreq_blacklist.begin();it!=rreq_blacklist.end();it++) 01185 { 01186 struct blacklist *blAux = it->second; 01187 if (bl == blAux) 01188 { 01189 rreq_blacklist.erase(it); 01190 01191 } 01192 } 01193 free(bl); 01194 } 01195 #endif 01196