NETWORK ATTACKS FRAMEWORK  1.0.0
A NETwork Attacks framework. Making network attacks impact evaluation easier!
NA_aodv_rreq.cc
Go to the documentation of this file.
00001 /*****************************************************************************
00002  *
00003  * Copyright (C) 2001 Uppsala University and Ericsson AB.
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation; either version 2 of the License, or
00008  * (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018  *
00019  * Authors: Erik Nordstr�, <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 
 All Classes Files Functions Variables Typedefs Enumerator Defines