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�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