NETWORK ATTACKS FRAMEWORK  1.0.0
A NETwork Attacks framework. Making network attacks impact evaluation easier!
NA_aodv_neighbor.cc
Go to the documentation of this file.
00001 /*****************************************************************************
00002  *
00003  * Copyright (C) 2001 Uppsala University and Ericsson AB.
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation; either version 2 of the License, or
00008  * (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018  *
00019  * Authors: Erik Nordström, <erik.nordstrom@it.uu.se>
00020  *
00021  *****************************************************************************/
00022 #define NS_PORT
00023 #define OMNETPP
00024 
00025 #ifdef NS_PORT
00026 #ifndef OMNETPP
00027 #include "ns/aodv-uu.h"
00028 #else
00029 #include "../NA_aodv_uu_omnet.h"
00030 #endif
00031 #else
00032 #include "NA_aodv_neighbor.h"
00033 #include "NA_aodv_rerr.h"
00034 #include "NA_aodv_hello.h"
00035 #include "NA_aodv_socket.h"
00036 #include "NA_routing_table.h"
00037 #include "NA_params.h"
00038 #include "NA_defs_aodv.h"
00039 #include "NA_debug_aodv.h"
00040 
00041 extern int llfeedback;
00042 #endif              /* NS_PORT */
00043 
00044 
00045 /* Add/Update neighbor from a non HELLO AODV control message... */
00046 void NS_CLASS neighbor_add(AODV_msg * aodv_msg, struct in_addr source,
00047                            unsigned int ifindex)
00048 {
00049     struct timeval now;
00050     rt_table_t *rt = NULL;
00051     u_int32_t seqno = 0;
00052     uint32_t cost;
00053     uint8_t fixhop;
00054 
00055     gettimeofday(&now, NULL);
00056 
00057     rt = rt_table_find(source);
00058 
00059     cost = costMobile;
00060     if (aodv_msg->prevFix)
00061     {
00062         fixhop=1;
00063         cost =  costStatic;
00064     }
00065 
00066     if (this->isStaticNode())
00067         fixhop++;
00068 
00069 
00070     if (!rt)
00071     {
00072         DEBUG(LOG_DEBUG, 0, "%s new NEIGHBOR!", ip_to_str(source));
00073         rt = rt_table_insert(source, source, 1, 0,
00074                              ACTIVE_ROUTE_TIMEOUT, VALID, 0, ifindex, cost, fixhop);
00075     }
00076     else
00077     {
00078         /* Don't update anything if this is a uni-directional link... */
00079         if (rt->flags & RT_UNIDIR)
00080             return;
00081 
00082         if (rt->dest_seqno != 0)
00083             seqno = rt->dest_seqno;
00084 
00085         rt_table_update(rt, source, 1, seqno, ACTIVE_ROUTE_TIMEOUT,
00086                         VALID, rt->flags, ifindex, cost, fixhop);
00087     }
00088 
00089     if (!llfeedback && rt->hello_timer.used)
00090         hello_update_timeout(rt, &now, ALLOWED_HELLO_LOSS * HELLO_INTERVAL);
00091 
00092     return;
00093 }
00094 
00095 #ifdef AODV_USE_STL_RT
00096 
00097 
00098 void NS_CLASS neighbor_link_break(rt_table_t * rt)
00099 {
00100     /* If hopcount = 1, this is a direct neighbor and a link break has
00101        occured. Send a RERR with the incremented sequence number */
00102     RERR *rerr = NULL;
00103     rt_table_t *rt_u;
00104     struct in_addr rerr_unicast_dest;
00105     int i;
00106 
00107     rerr_unicast_dest.s_addr = ManetAddress::ZERO;
00108 
00109     if (!rt)
00110         return;
00111 
00112     if (rt->hcnt != 1)
00113     {
00114         DEBUG(LOG_DEBUG, 0, "%s is not a neighbor, hcnt=%d!!!",
00115               ip_to_str(rt->dest_addr), rt->hcnt);
00116         return;
00117     }
00118 
00119     DEBUG(LOG_DEBUG, 0, "Link %s down!", ip_to_str(rt->dest_addr));
00120 
00121     /* Invalidate the entry of the route that broke or timed out... */
00122     rt_table_invalidate(rt);
00123 
00124     /* Create a route error msg, unless the route is to be repaired */
00125     if (rt->nprec && !(rt->flags & RT_REPAIR))
00126     {
00127         rerr = rerr_create(0, rt->dest_addr, rt->dest_seqno);
00128         DEBUG(LOG_DEBUG, 0, "Added %s as unreachable, seqno=%lu",
00129               ip_to_str(rt->dest_addr), rt->dest_seqno);
00130 
00131         if (rt->nprec == 1)
00132             rerr_unicast_dest = rt->precursors[0].neighbor;
00133     }
00134 
00135     /* Purge precursor list: */
00136     if (!(rt->flags & RT_REPAIR))
00137         precursor_list_destroy(rt);
00138 
00139     /* Check the routing table for entries which have the unreachable
00140        destination (dest) as next hop. These entries (destinations)
00141        cannot be reached either since dest is down. They should
00142        therefore also be included in the RERR. */
00143     for (AodvRtTableMap::iterator it = aodvRtTableMap.begin(); it != aodvRtTableMap.end(); it++)
00144     {
00145         rt_table_t *rt_u = it->second;;
00146         if (rt_u->state == VALID &&
00147                 rt_u->next_hop.s_addr == rt->dest_addr.s_addr &&
00148                 rt_u->dest_addr.s_addr != rt->dest_addr.s_addr)
00149         {
00150             /* If the link that broke are marked for repair,
00151              *                    then do the same for all additional unreachable
00152              *                                       destinations. */
00153 
00154             if ((rt->flags & RT_REPAIR) && rt_u->hcnt <= MAX_REPAIR_TTL)
00155             {
00156                 rt_u->flags |= RT_REPAIR;
00157                 DEBUG(LOG_DEBUG, 0, "Marking %s for REPAIR",
00158                         ip_to_str(rt_u->dest_addr));
00159                 rt_table_invalidate(rt_u);
00160                 continue;
00161             }
00162             rt_table_invalidate(rt_u);
00163             if (!rt_u->precursors.empty())
00164             {
00165                 if (!rerr)
00166                 {
00167                     rerr = rerr_create(0, rt_u->dest_addr, rt_u->dest_seqno);
00168                     if (rt_u->precursors.size() == 1)
00169                         rerr_unicast_dest = rt_u->precursors[0].neighbor;
00170                         DEBUG(LOG_DEBUG, 0,
00171                               "Added %s as unreachable, seqno=%lu",
00172                               ip_to_str(rt_u->dest_addr), rt_u->dest_seqno);
00173                 }
00174                 else
00175                 {
00176                     /* Decide whether new precursors make this a non unicast RERR */
00177                     rerr_add_udest(rerr, rt_u->dest_addr, rt_u->dest_seqno);
00178                     if (!rerr_unicast_dest.s_addr.isUnspecified())
00179                     {
00180                         for (unsigned int i = 0; i< rt_u->precursors.size(); i++)
00181                         {
00182                             precursor_t pr = rt_u->precursors[i];
00183                             if (pr.neighbor.s_addr != rerr_unicast_dest.s_addr)
00184                             {
00185                                 rerr_unicast_dest.s_addr = ManetAddress::ZERO;
00186                                 break;
00187                             }
00188                         }
00189                     }
00190                     DEBUG(LOG_DEBUG, 0, "Added %s as unreachable, seqno=%lu",ip_to_str(rt_u->dest_addr), rt_u->dest_seqno);
00191                 }
00192             }
00193             precursor_list_destroy(rt_u);
00194         }
00195     }
00196 
00197     if (rerr)
00198     {
00199         DEBUG(LOG_DEBUG, 0, "RERR created, %d bytes.", RERR_CALC_SIZE(rerr));
00200 
00201         rt_u = rt_table_find(rerr_unicast_dest);
00202 
00203         if (rt_u && rerr->dest_count == 1 && (!rerr_unicast_dest.s_addr.isUnspecified()))
00204             aodv_socket_send((AODV_msg *) rerr,
00205                              rerr_unicast_dest,
00206                              RERR_CALC_SIZE(rerr), 1,
00207                              &DEV_IFINDEX(rt_u->ifindex));
00208 
00209         else if (rerr->dest_count > 0)
00210         {
00211             /* FIXME: Should only transmit RERR on those interfaces
00212              *       * which have precursor nodes for the broken route */
00213             double delay = -1;
00214             if (par("EqualDelay"))
00215                 delay = par("broadcastDelay");
00216             int cont = getNumWlanInterfaces();
00217             for (i = 0; i < MAX_NR_INTERFACES; i++)
00218             {
00219                 struct in_addr dest;
00220                 if (!DEV_NR(i).enabled)
00221                     continue;
00222                 dest.s_addr = ManetAddress(IPv4Address(AODV_BROADCAST));
00223                 if (cont>1)
00224                     aodv_socket_send((AODV_msg *) rerr->dup(), dest,
00225                                      RERR_CALC_SIZE(rerr), 1, &DEV_NR(i),delay);
00226                 else
00227                     aodv_socket_send((AODV_msg *) rerr, dest,
00228                                      RERR_CALC_SIZE(rerr), 1, &DEV_NR(i),delay);
00229                 cont--;
00230             }
00231         }
00232         else
00233             delete rerr;
00234     }
00235 }
00236 #else
00237 
00238 void NS_CLASS neighbor_link_break(rt_table_t * rt)
00239 {
00240     /* If hopcount = 1, this is a direct neighbor and a link break has
00241        occured. Send a RERR with the incremented sequence number */
00242     RERR *rerr = NULL;
00243     rt_table_t *rt_u;
00244     struct in_addr rerr_unicast_dest;
00245     int i;
00246 
00247     rerr_unicast_dest.s_addr = 0;
00248 
00249     if (!rt)
00250         return;
00251 
00252     if (rt->hcnt != 1)
00253     {
00254         DEBUG(LOG_DEBUG, 0, "%s is not a neighbor, hcnt=%d!!!",
00255               ip_to_str(rt->dest_addr), rt->hcnt);
00256         return;
00257     }
00258 
00259     DEBUG(LOG_DEBUG, 0, "Link %s down!", ip_to_str(rt->dest_addr));
00260 
00261     /* Invalidate the entry of the route that broke or timed out... */
00262     rt_table_invalidate(rt);
00263 
00264     /* Create a route error msg, unless the route is to be repaired */
00265     if (rt->nprec && !(rt->flags & RT_REPAIR))
00266     {
00267         rerr = rerr_create(0, rt->dest_addr, rt->dest_seqno);
00268         DEBUG(LOG_DEBUG, 0, "Added %s as unreachable, seqno=%lu",
00269               ip_to_str(rt->dest_addr), rt->dest_seqno);
00270 
00271         if (rt->nprec == 1)
00272             rerr_unicast_dest = FIRST_PREC(rt->precursors)->neighbor;
00273     }
00274 
00275     /* Purge precursor list: */
00276     if (!(rt->flags & RT_REPAIR))
00277         precursor_list_destroy(rt);
00278 
00279     /* Check the routing table for entries which have the unreachable
00280        destination (dest) as next hop. These entries (destinations)
00281        cannot be reached either since dest is down. They should
00282        therefore also be included in the RERR. */
00283     for (i = 0; i < RT_TABLESIZE; i++)
00284     {
00285         list_t *pos;
00286         list_foreach(pos, &rt_tbl.tbl[i])
00287         {
00288             rt_table_t *rt_u = (rt_table_t *) pos;
00289 
00290             if (rt_u->state == VALID &&
00291                     rt_u->next_hop.s_addr == rt->dest_addr.s_addr &&
00292                     rt_u->dest_addr.s_addr != rt->dest_addr.s_addr)
00293             {
00294 
00295                 /* If the link that broke are marked for repair,
00296                    then do the same for all additional unreachable
00297                    destinations. */
00298 
00299                 if ((rt->flags & RT_REPAIR) && rt_u->hcnt <= MAX_REPAIR_TTL)
00300                 {
00301 
00302                     rt_u->flags |= RT_REPAIR;
00303                     DEBUG(LOG_DEBUG, 0, "Marking %s for REPAIR",
00304                           ip_to_str(rt_u->dest_addr));
00305 
00306                     rt_table_invalidate(rt_u);
00307                     continue;
00308                 }
00309 
00310                 rt_table_invalidate(rt_u);
00311 
00312                 if (rt_u->nprec)
00313                 {
00314 
00315                     if (!rerr)
00316                     {
00317                         rerr =
00318                             rerr_create(0, rt_u->dest_addr, rt_u->dest_seqno);
00319 
00320                         if (rt_u->nprec == 1)
00321                             rerr_unicast_dest =
00322                                 FIRST_PREC(rt_u->precursors)->neighbor;
00323 
00324                         DEBUG(LOG_DEBUG, 0,
00325                               "Added %s as unreachable, seqno=%lu",
00326                               ip_to_str(rt_u->dest_addr), rt_u->dest_seqno);
00327                     }
00328                     else
00329                     {
00330                         /* Decide whether new precursors make this a non unicast
00331                            RERR */
00332                         rerr_add_udest(rerr, rt_u->dest_addr, rt_u->dest_seqno);
00333 
00334                         if (rerr_unicast_dest.s_addr)
00335                         {
00336                             list_t *pos2;
00337                             list_foreach(pos2, &rt_u->precursors)
00338                             {
00339                                 precursor_t *pr = (precursor_t *) pos2;
00340                                 if (pr->neighbor.s_addr !=
00341                                         rerr_unicast_dest.s_addr)
00342                                 {
00343                                     rerr_unicast_dest.s_addr = 0;
00344                                     break;
00345                                 }
00346                             }
00347                         }
00348                         DEBUG(LOG_DEBUG, 0,
00349                               "Added %s as unreachable, seqno=%lu",
00350                               ip_to_str(rt_u->dest_addr), rt_u->dest_seqno);
00351                     }
00352                 }
00353                 precursor_list_destroy(rt_u);
00354             }
00355         }
00356     }
00357 
00358     if (rerr)
00359     {
00360         DEBUG(LOG_DEBUG, 0, "RERR created, %d bytes.", RERR_CALC_SIZE(rerr));
00361 
00362         rt_u = rt_table_find(rerr_unicast_dest);
00363 
00364         if (rt_u && rerr->dest_count == 1 && (rerr_unicast_dest.s_addr!=0))
00365             aodv_socket_send((AODV_msg *) rerr,
00366                              rerr_unicast_dest,
00367                              RERR_CALC_SIZE(rerr), 1,
00368                              &DEV_IFINDEX(rt_u->ifindex));
00369 
00370         else if (rerr->dest_count > 0)
00371         {
00372             /* FIXME: Should only transmit RERR on those interfaces
00373              *       * which have precursor nodes for the broken route */
00374 #ifdef OMNETPP
00375             double delay = -1;
00376             if (par("EqualDelay"))
00377                 delay = par("broadcastDelay");
00378             int cont = getNumWlanInterfaces();
00379 #endif
00380             for (i = 0; i < MAX_NR_INTERFACES; i++)
00381             {
00382                 struct in_addr dest;
00383                 if (!DEV_NR(i).enabled)
00384                     continue;
00385                 dest.s_addr = AODV_BROADCAST;
00386 #ifdef OMNETPP
00387                 if (cont>1)
00388                     aodv_socket_send((AODV_msg *) rerr->dup(), dest,
00389                                      RERR_CALC_SIZE(rerr), 1, &DEV_NR(i),delay);
00390                 else
00391                     aodv_socket_send((AODV_msg *) rerr, dest,
00392                                      RERR_CALC_SIZE(rerr), 1, &DEV_NR(i),delay);
00393                 cont--;
00394 #else
00395                 aodv_socket_send((AODV_msg *) rerr, dest,
00396                                  RERR_CALC_SIZE(rerr), 1, &DEV_NR(i));
00397 #endif
00398             }
00399         }
00400 #ifdef OMNETPP
00401         else
00402             delete rerr;
00403 #endif
00404     }
00405 }
00406 #endif
00407 
 All Classes Files Functions Variables Typedefs Enumerator Defines