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