NETWORK ATTACKS FRAMEWORK  1.0.0
A NETwork Attacks framework. Making network attacks impact evaluation easier!
NA_aodv_hello.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  *****************************************************************************/
00023 #define NS_PORT
00024 #define OMNETPP
00025 
00026 #ifdef NS_PORT
00027 #ifndef OMNETPP
00028 #include "ns/aodv-uu.h"
00029 #else
00030 #include "../NA_aodv_uu_omnet.h"
00031 #endif
00032 #else
00033 #include <netinet/in.h>
00034 #include "NA_aodv_hello.h"
00035 #include "NA_aodv_timeout.h"
00036 #include "NA_aodv_rrep.h"
00037 #include "NA_aodv_rreq.h"
00038 #include "NA_routing_table.h"
00039 #include "NA_timer_queue_aodv.h"
00040 #include "NA_params.h"
00041 #include "NA_aodv_socket.h"
00042 #include "NA_defs_aodv.h"
00043 #include "NA_debug_aodv.h"
00044 #define DEBUG_HELLO
00045 extern int unidir_hack, receive_n_hellos, hello_jittering, optimized_hellos;
00046 static struct timer hello_timer;
00047 
00048 #endif
00049 
00050 /* #define DEBUG_HELLO */
00051 
00052 
00053 long NS_CLASS hello_jitter()
00054 {
00055     if (hello_jittering)
00056     {
00057 #ifdef NS_PORT
00058 #ifndef OMNETPP
00059         return (long) (((float) Random::integer(RAND_MAX + 1) / RAND_MAX - 0.5)
00060                        * JITTER_INTERVAL);
00061 #else
00062         return (long) (((float) intuniform(0, RAND_MAX) / RAND_MAX - 0.5)
00063                        * JITTER_INTERVAL);
00064 #endif
00065 #else
00066         return (long) (((float) random() / RAND_MAX - 0.5) * JITTER_INTERVAL);
00067 #endif
00068     }
00069     else
00070         return 0;
00071 }
00072 
00073 void NS_CLASS hello_start()
00074 {
00075     if (hello_timer.used)
00076         return;
00077 
00078     gettimeofday(&this_host.fwd_time, NULL);
00079 
00080     DEBUG(LOG_DEBUG, 0, "Starting to send HELLOs!");
00081     timer_init(&hello_timer, &NS_CLASS hello_send, NULL);
00082 
00083     hello_send(NULL);
00084 }
00085 
00086 void NS_CLASS hello_stop()
00087 {
00088     DEBUG(LOG_DEBUG, 0,
00089           "No active forwarding routes - stopped sending HELLOs!");
00090 #ifdef OMNETPP
00091     EV << "No active forwarding routes - stopped sending HELLOs!";
00092 #endif
00093     timer_remove(&hello_timer);
00094 }
00095 
00096 void NS_CLASS hello_send(void *arg)
00097 {
00098     RREP *rrep;
00099     AODV_ext *ext = NULL;
00100     u_int8_t flags = 0;
00101     struct in_addr dest;
00102     long time_diff, jitter;
00103     struct timeval now;
00104     int msg_size = RREP_SIZE;
00105     int i;
00106     char buffer[300];
00107     char *buffer_ptr;
00108 
00109     buffer_ptr = buffer;
00110 
00111     gettimeofday(&now, NULL);
00112 
00113     if (optimized_hellos &&
00114             timeval_diff(&now, &this_host.fwd_time) > ACTIVE_ROUTE_TIMEOUT)
00115     {
00116         hello_stop();
00117         return;
00118     }
00119 
00120 #ifdef OMNETPP
00121     double delay = -1;
00122     if (par("EqualDelay"))
00123         delay = par("broadcastDelay");
00124 #endif
00125 
00126     time_diff = timeval_diff(&now, &this_host.bcast_time);
00127     jitter = hello_jitter();
00128 
00129     /* This check will ensure we don't send unnecessary hello msgs, in case
00130        we have sent other bcast msgs within HELLO_INTERVAL */
00131     if (time_diff >= HELLO_INTERVAL)
00132     {
00133 
00134         for (i = 0; i < MAX_NR_INTERFACES; i++)
00135         {
00136             if (!DEV_NR(i).enabled)
00137                 continue;
00138 #ifdef DEBUG_HELLO
00139             DEBUG(LOG_DEBUG, 0, "sending Hello to 255.255.255.255");
00140 #endif
00141 #ifdef OMNETPP
00142             EV << "sending Hello to 255.255.255.255";
00143 #endif
00144             rrep = rrep_create(flags, 0, 0, DEV_NR(i).ipaddr,
00145                                this_host.seqno,
00146                                DEV_NR(i).ipaddr,
00147                                ALLOWED_HELLO_LOSS * HELLO_INTERVAL);
00148 
00149             /* Assemble a RREP extension which contain our neighbor set... */
00150             if (unidir_hack)
00151             {
00152                 int i;
00153 #ifndef OMNETPP
00154                 if (ext)
00155                     ext = AODV_EXT_NEXT(ext);
00156                 else
00157                     /* Check for hello interval extension: */
00158                     ext = (AODV_ext *) ((char *) rrep + RREP_SIZE);
00159                 ext->type = RREP_HELLO_NEIGHBOR_SET_EXT;
00160                 ext->length = 0;
00161 #endif
00162 
00163                 for (i = 0; i < RT_TABLESIZE; i++)
00164                 {
00165                     list_t *pos;
00166                     list_foreach(pos, &rt_tbl.tbl[i])
00167                     {
00168                         rt_table_t *rt = (rt_table_t *) pos;
00169                         /* If an entry has an active hello timer, we assume
00170                            that we are receiving hello messages from that
00171                            node... */
00172                         if (rt->hello_timer.used)
00173                         {
00174 #ifdef DEBUG_HELLO
00175                             DEBUG(LOG_INFO, 0,
00176                                   "Adding %s to hello neighbor set ext",
00177                                   ip_to_str(rt->dest_addr));
00178 #endif
00179 #ifndef OMNETPP
00180                             memcpy(AODV_EXT_NEXT(ext), &rt->dest_addr,
00181                                    sizeof(struct in_addr));
00182                             ext->length += sizeof(struct in_addr);
00183 #else
00184                             memcpy(buffer_ptr, &rt->dest_addr,
00185                                    sizeof(struct in_addr));
00186                             buffer_ptr+=sizeof(struct in_addr);
00187 #endif
00188 
00189                         }
00190                     }
00191                 }
00192 #ifdef OMNETPP
00193                 if (ext->length)
00194                 {
00195                     msg_size = RREP_SIZE + AODV_EXT_SIZE(ext);
00196 
00197                 }
00198                 rrep->setName("AodvHello");
00199                 rrep->setByteLength(msg_size);
00200 #else
00201                 if (buffer_ptr-buffer>0)
00202                 {
00203                     rrep->addExtension(RREP_HELLO_NEIGHBOR_SET_EXT,(int)(buffer_ptr-buffer),buffer);
00204                     msg_size = RREP_SIZE + (int)(buffer_ptr-buffer);
00205                 }
00206 
00207 #endif
00208             }
00209             dest.s_addr = ManetAddress(IPv4Address(AODV_BROADCAST));
00210 #ifdef OMNETPP
00211             rrep->ttl=1;
00212             aodv_socket_send((AODV_msg *) rrep, dest, msg_size, 1, &DEV_NR(i),delay);
00213 #else
00214             aodv_socket_send((AODV_msg *) rrep, dest, msg_size, 1, &DEV_NR(i));
00215 #endif
00216         }
00217 
00218         timer_set_timeout(&hello_timer, HELLO_INTERVAL + jitter);
00219     }
00220     else
00221     {
00222         if (HELLO_INTERVAL - time_diff + jitter < 0)
00223             timer_set_timeout(&hello_timer,
00224                               HELLO_INTERVAL - time_diff - jitter);
00225         else
00226             timer_set_timeout(&hello_timer,
00227                               HELLO_INTERVAL - time_diff + jitter);
00228     }
00229 }
00230 
00231 
00232 /* Process a hello message */
00233 void NS_CLASS hello_process(RREP * hello, int rreplen, unsigned int ifindex)
00234 {
00235     u_int32_t hello_seqno, timeout, hello_interval = HELLO_INTERVAL;
00236     u_int8_t state, flags = 0;
00237     struct in_addr ext_neighbor, hello_dest;
00238     rt_table_t *rt;
00239     AODV_ext *ext = NULL;
00240     struct timeval now;
00241 
00242     uint32_t cost;
00243     uint8_t fixhop;
00244 
00245     cost = costMobile;
00246     if (hello->prevFix)
00247     {
00248         fixhop=1;
00249         cost =  costStatic;
00250     }
00251 
00252     if (this->isStaticNode())
00253         fixhop++;
00254 
00255     gettimeofday(&now, NULL);
00256 
00257     hello_dest.s_addr = hello->dest_addr;
00258     hello_seqno = ntohl(hello->dest_seqno);
00259 
00260     rt = rt_table_find(hello_dest);
00261 
00262     if (rt)
00263         flags = rt->flags;
00264 
00265     if (unidir_hack)
00266         flags |= RT_UNIDIR;
00267 #ifndef OMNETPP
00268     /* Check for hello interval extension: */
00269     ext = (AODV_ext *) ((char *) hello + RREP_SIZE);
00270     while (rreplen > (int) RREP_SIZE)
00271     {
00272 #else
00273     ext = hello->getFirstExtension();
00274     for (int i=0; i<hello->getNumExtension (); i++)
00275     {
00276 #endif
00277         switch (ext->type)
00278         {
00279         case RREP_HELLO_INTERVAL_EXT:
00280             if (ext->length == 4)
00281             {
00282                 memcpy(&hello_interval, AODV_EXT_DATA(ext), 4);
00283                 hello_interval = ntohl(hello_interval);
00284 #ifdef DEBUG_HELLO
00285                 DEBUG(LOG_INFO, 0, "Hello extension interval=%lu!",
00286                       hello_interval);
00287 #endif
00288 #ifdef OMNETPP
00289                 EV << "Hello extension interval = "<< hello_interval;
00290 #endif
00291 
00292             }
00293             else
00294                 alog(LOG_WARNING, 0,
00295                      __FUNCTION__, "Bad hello interval extension!");
00296             break;
00297         case RREP_HELLO_NEIGHBOR_SET_EXT:
00298 
00299 #ifdef DEBUG_HELLO
00300             DEBUG(LOG_INFO, 0, "RREP_HELLO_NEIGHBOR_SET_EXT");
00301 #endif
00302 #ifdef OMNETPP
00303             EV << "RREP_HELLO_NEIGHBOR_SET_EXT";
00304 #endif
00305 
00306             for (i = 0; i < ext->length; i = i + 4)
00307             {
00308                 ext_neighbor.s_addr =
00309                         ManetAddress(IPv4Address(*(in_addr_t *) ((char *) AODV_EXT_DATA(ext) + i)));
00310 
00311                 if (ext_neighbor.s_addr == DEV_IFINDEX(ifindex).ipaddr.s_addr)
00312                     flags &= ~RT_UNIDIR;
00313             }
00314             break;
00315         default:
00316             alog(LOG_WARNING, 0, __FUNCTION__,
00317                  "Bad extension!! type=%d, length=%d", ext->type, ext->length);
00318             ext = NULL;
00319             break;
00320         }
00321         if (ext == NULL)
00322             break;
00323 
00324         rreplen -= AODV_EXT_SIZE(ext);
00325         ext = AODV_EXT_NEXT(ext);
00326     }
00327 
00328 #ifdef DEBUG_HELLO
00329     DEBUG(LOG_DEBUG, 0, "rcvd HELLO from %s, seqno %lu",
00330           ip_to_str(hello_dest), hello_seqno);
00331 #endif
00332 #ifdef OMNETPP
00333     EV << "rcvd HELLO from " << ip_to_str(hello_dest) << " seqno = hello_seqno";
00334 #endif
00335 
00336     /* This neighbor should only be valid after receiving 3
00337        consecutive hello messages... */
00338     if (receive_n_hellos)
00339         state = INVALID;
00340     else
00341         state = VALID;
00342 
00343     timeout = ALLOWED_HELLO_LOSS * hello_interval + ROUTE_TIMEOUT_SLACK;
00344 
00345     if (!rt)
00346     {
00347         /* No active or expired route in the routing table. So we add a
00348            new entry... */
00349 
00350         rt = rt_table_insert(hello_dest, hello_dest, 1,
00351                              hello_seqno, timeout, state, flags, ifindex,cost,fixhop);
00352 
00353         if (flags & RT_UNIDIR)
00354         {
00355             DEBUG(LOG_INFO, 0, "%s new NEIGHBOR, link UNI-DIR",
00356                   ip_to_str(rt->dest_addr));
00357         }
00358         else
00359         {
00360             DEBUG(LOG_INFO, 0, "%s new NEIGHBOR!", ip_to_str(rt->dest_addr));
00361         }
00362         rt->hello_cnt = 1;
00363 
00364     }
00365     else
00366     {
00367 
00368         if ((flags & RT_UNIDIR) && rt->state == VALID && rt->hcnt > 1)
00369         {
00370             goto hello_update;
00371         }
00372 
00373         if (receive_n_hellos && rt->hello_cnt < (receive_n_hellos - 1))
00374         {
00375             if (timeval_diff(&now, &rt->last_hello_time) <
00376                     (long) (hello_interval + hello_interval / 2))
00377                 rt->hello_cnt++;
00378             else
00379                 rt->hello_cnt = 1;
00380 
00381             memcpy(&rt->last_hello_time, &now, sizeof(struct timeval));
00382             return;
00383         }
00384         rt_table_update(rt, hello_dest, 1, hello_seqno, timeout, VALID, flags, ifindex, cost, fixhop);
00385     }
00386 
00387 hello_update:
00388 
00389     hello_update_timeout(rt, &now, ALLOWED_HELLO_LOSS * hello_interval);
00390     return;
00391 }
00392 
00393 
00394 #define HELLO_DELAY 50      /* The extra time we should allow an hello
00395 message to take (due to processing) before
00396 assuming lost . */
00397 
00398 NS_INLINE void NS_CLASS hello_update_timeout(rt_table_t * rt,
00399         struct timeval *now, long time)
00400 {
00401     timer_set_timeout(&rt->hello_timer, time + HELLO_DELAY);
00402     memcpy(&rt->last_hello_time, now, sizeof(struct timeval));
00403 }
00404 
 All Classes Files Functions Variables Typedefs Enumerator Defines