NETWORK ATTACKS FRAMEWORK
1.0.0
A NETwork Attacks framework. Making network attacks impact evaluation easier!
|
00001 /***************************************************************************** 00002 * 00003 * Copyright (C) 2001 Uppsala University & 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 #include "NA_aodv_uu_omnet.h" 00024 #include "IPv4Datagram.h" 00025 00026 #define GARBAGE_COLLECT 00027 00028 #ifndef AODV_USE_STL 00029 void NS_CLASS packet_queue_init(void) 00030 { 00031 INIT_LIST_HEAD(&PQ.head); 00032 PQ.len = 0; 00033 00034 #ifdef GARBAGE_COLLECT 00035 /* Set up garbage collector */ 00036 timer_init(&PQ.garbage_collect_timer, &NS_CLASS packet_queue_timeout, &PQ); 00037 00038 timer_set_timeout(&PQ.garbage_collect_timer, GARBAGE_COLLECT_TIME); 00039 #endif 00040 } 00041 00042 00043 void NS_CLASS packet_queue_destroy(void) 00044 { 00045 int count = 0; 00046 list_t *pos, *tmp; 00047 00048 list_foreach_safe(pos, tmp, &PQ.head) 00049 { 00050 struct q_pkt *qp = (struct q_pkt *)pos; 00051 list_detach(pos); 00052 00053 delete qp->p; 00054 00055 free(qp); 00056 count++; 00057 PQ.len--; 00058 } 00059 00060 DEBUG(LOG_INFO, 0, "Destroyed %d buffered packets!", count); 00061 } 00062 00063 /* Garbage collect packets which have been queued for too long... */ 00064 int NS_CLASS packet_queue_garbage_collect(void) 00065 { 00066 int count = 0; 00067 list_t *pos, *tmp; 00068 struct timeval now; 00069 00070 gettimeofday(&now, NULL); 00071 00072 list_foreach_safe(pos, tmp, &PQ.head) 00073 { 00074 struct q_pkt *qp = (struct q_pkt *)pos; 00075 if (timeval_diff(&now, &qp->q_time) > MAX_QUEUE_TIME) 00076 { 00077 list_detach(pos); 00078 //icmpAccess.get()->sendErrorMessage(qp->p, ICMP_DESTINATION_UNREACHABLE, 0); 00079 // drop (qp->p); 00080 sendICMP(qp->p); 00081 free(qp); 00082 count++; 00083 PQ.len--; 00084 } 00085 } 00086 00087 if (count) 00088 { 00089 DEBUG(LOG_DEBUG, 0, "Removed %d packet(s)!", count); 00090 } 00091 00092 return count; 00093 } 00094 /* Buffer a packet in a FIFO queue. Implemented as a linked list, 00095 where we add elements at the end and remove at the beginning.... */ 00096 00097 void NS_CLASS packet_queue_add(cPacket * p, struct in_addr dest_addr) 00098 { 00099 struct q_pkt *qp; 00100 cPacket *dgram; 00101 00102 if (PQ.len >= MAX_QUEUE_LENGTH) 00103 { 00104 DEBUG(LOG_DEBUG, 0, "MAX Queue length! Removing first packet."); 00105 if (!list_empty(&PQ.head)) 00106 { 00107 qp = (struct q_pkt *)PQ.head.next; 00108 list_detach(PQ.head.next); 00109 dgram = qp->p; 00110 // drop (dgram); 00111 sendICMP(dgram); 00112 // icmpAccess.get()->sendErrorMessage(dgram, ICMP_DESTINATION_UNREACHABLE, ICMP_AODV_QUEUE_FULL); 00113 free(qp); 00114 PQ.len--; 00115 } 00116 } 00117 00118 qp = (struct q_pkt *) malloc(sizeof(struct q_pkt)); 00119 00120 if (qp == NULL) 00121 { 00122 fprintf(stderr, "Malloc failed!\n"); 00123 exit(-1); 00124 } 00125 00126 qp->p = p; 00127 qp->dest_addr = dest_addr; 00128 00129 gettimeofday(&qp->q_time, NULL); 00130 00131 list_add_tail(&PQ.head, &qp->l); 00132 00133 PQ.len++; 00134 00135 DEBUG(LOG_INFO, 0, "buffered pkt to %s qlen=%u", 00136 ip_to_str(dest_addr), PQ.len); 00137 } 00138 00139 int NS_CLASS packet_queue_set_verdict(struct in_addr dest_addr, int verdict) 00140 { 00141 int count = 0; 00142 rt_table_t *rt, *next_hop_rt, *inet_rt = NULL; 00143 list_t *pos, *tmp; 00144 struct in_addr gw_addr; 00145 00146 double delay = 0; 00147 #define ARP_DELAY 0.005 00148 00149 if (verdict == PQ_ENC_SEND) 00150 { 00151 gw_addr.s_addr = gateWayAddress->getInt(); 00152 rt = rt_table_find(gw_addr); 00153 } 00154 else 00155 rt = rt_table_find(dest_addr); 00156 00157 std::vector<ManetAddress> list; 00158 if (isInMacLayer()) 00159 { 00160 std::vector<MACAddress> listMac; 00161 getApList(MACAddress(dest_addr.s_addr.getLo()),listMac); 00162 while (!listMac.empty()) 00163 { 00164 list.push_back(listMac.back().getInt()); 00165 listMac.pop_back(); 00166 } 00167 } 00168 else 00169 { 00170 std::vector<IPv4Address> listIp; 00171 getApListIp(IPv4Address(dest_addr.s_addr.getLo()),listIp); 00172 while (!listIp.empty()) 00173 { 00174 list.push_back(listIp.back().getInt()); 00175 listIp.pop_back(); 00176 } 00177 } 00178 00179 while (!list.empty()) 00180 { 00181 struct in_addr dest_addr; 00182 dest_addr.s_addr = list.back(); 00183 list.pop_back(); 00184 list_foreach_safe(pos, tmp, &PQ.head) 00185 { 00186 00187 struct q_pkt *qp = (struct q_pkt *)pos; 00188 if (qp->dest_addr.s_addr == dest_addr.s_addr) 00189 { 00190 list_detach(pos); 00191 00192 switch (verdict) 00193 { 00194 case PQ_ENC_SEND: 00195 if (dynamic_cast <IPv4Datagram *> (qp->p)) 00196 { 00197 qp->p = pkt_encapsulate(dynamic_cast <IPv4Datagram *> (qp->p), *gateWayAddress); 00198 // now Ip layer decremented again 00199 /* Apparently, the link layer implementation can't handle 00200 a burst of packets. So to keep ARP happy, buffered * * 00201 packets are sent with ARP_DELAY seconds between sends. */ 00202 sendDelayed(qp->p, delay, "to_ip"); 00203 delay += ARP_DELAY; 00204 } 00205 else 00206 { 00207 // drop(qp->p); 00208 sendICMP(qp->p); 00209 } 00210 break; 00211 case PQ_SEND: 00212 if (!rt) 00213 return -1; 00214 /* Apparently, the link layer implementation can't handle 00215 * a burst of packets. So to keep ARP happy, buffered 00216 * packets are sent with ARP_DELAY seconds between 00217 * sends. */ 00218 // now Ip layer decremented again 00219 sendDelayed(qp->p, delay, "to_ip"); 00220 delay += ARP_DELAY; 00221 break; 00222 case PQ_DROP: 00223 //drop(qp->p); 00224 sendICMP(qp->p); 00225 00226 // icmpAccess.get()->sendErrorMessage(qp->p, ICMP_DESTINATION_UNREACHABLE, 0); 00227 break; 00228 } 00229 free(qp); 00230 count++; 00231 PQ.len--; 00232 } 00233 } 00234 } 00235 00236 /* Update rt timeouts */ 00237 if (rt && rt->state == VALID && 00238 (verdict == PQ_SEND || verdict == PQ_ENC_SEND)) 00239 { 00240 if (dest_addr.s_addr != DEV_IFINDEX(rt->ifindex).ipaddr.s_addr) 00241 { 00242 if (verdict == PQ_ENC_SEND && inet_rt) 00243 rt_table_update_timeout(inet_rt, ACTIVE_ROUTE_TIMEOUT); 00244 00245 rt_table_update_timeout(rt, ACTIVE_ROUTE_TIMEOUT); 00246 00247 next_hop_rt = rt_table_find(rt->next_hop); 00248 00249 if (next_hop_rt && next_hop_rt->state == VALID && 00250 next_hop_rt->dest_addr.s_addr != rt->dest_addr.s_addr) 00251 rt_table_update_timeout(next_hop_rt, ACTIVE_ROUTE_TIMEOUT); 00252 } 00253 00254 DEBUG(LOG_INFO, 0, "SENT %d packets to %s qlen=%u", 00255 count, ip_to_str(dest_addr), PQ.len); 00256 } 00257 else if (verdict == PQ_DROP) 00258 { 00259 DEBUG(LOG_INFO, 0, "DROPPED %d packets for %s!", 00260 count, ip_to_str(dest_addr)); 00261 } 00262 00263 return count; 00264 } 00265 #else 00266 void NS_CLASS packet_queue_init(void) 00267 { 00268 PQ.pkQueue.clear(); 00269 #ifdef GARBAGE_COLLECT 00270 /* Set up garbage collector */ 00271 timer_init(&PQ.garbage_collect_timer, &NS_CLASS packet_queue_timeout, &PQ); 00272 00273 timer_set_timeout(&PQ.garbage_collect_timer, GARBAGE_COLLECT_TIME); 00274 #endif 00275 } 00276 00277 00278 void NS_CLASS packet_queue_destroy(void) 00279 { 00280 int count = 0; 00281 while (!PQ.pkQueue.empty()) 00282 { 00283 struct q_pkt *qp = PQ.pkQueue.back(); 00284 PQ.pkQueue.pop_back(); 00285 delete qp->p; 00286 free(qp); 00287 count++; 00288 } 00289 DEBUG(LOG_INFO, 0, "Destroyed %d buffered packets!", count); 00290 } 00291 00292 /* Garbage collect packets which have been queued for too long... */ 00293 int NS_CLASS packet_queue_garbage_collect(void) 00294 { 00295 int count = 0; 00296 struct timeval now; 00297 00298 gettimeofday(&now, NULL); 00299 00300 for (unsigned int i=0; i < PQ.pkQueue.size();) 00301 { 00302 struct q_pkt *qp = PQ.pkQueue[i]; 00303 if (timeval_diff(&now, &qp->q_time) > MAX_QUEUE_TIME) 00304 { 00305 PQ.pkQueue.erase(PQ.pkQueue.begin()+i); 00306 sendICMP(qp->p); 00307 free(qp); 00308 count++; 00309 } 00310 else 00311 i++; 00312 } 00313 00314 if (count) 00315 { 00316 DEBUG(LOG_DEBUG, 0, "Removed %d packet(s)!", count); 00317 } 00318 00319 return count; 00320 } 00321 /* Buffer a packet in a FIFO queue. Implemented as a linked list, 00322 where we add elements at the end and remove at the beginning.... */ 00323 00324 void NS_CLASS packet_queue_add(cPacket * p, struct in_addr dest_addr) 00325 { 00326 struct q_pkt *qp; 00327 cPacket *dgram; 00328 00329 if (PQ.pkQueue.size() >= MAX_QUEUE_LENGTH) 00330 { 00331 DEBUG(LOG_DEBUG, 0, "MAX Queue length! Removing first packet."); 00332 qp = PQ.pkQueue.front(); 00333 PQ.pkQueue.erase(PQ.pkQueue.begin()); 00334 dgram = qp->p; 00335 sendICMP(dgram); 00336 free(qp); 00337 } 00338 00339 qp = (struct q_pkt *) malloc(sizeof(struct q_pkt)); 00340 00341 if (qp == NULL) 00342 { 00343 fprintf(stderr, "Malloc failed!\n"); 00344 exit(-1); 00345 } 00346 qp->p = p; 00347 qp->dest_addr = dest_addr; 00348 00349 gettimeofday(&qp->q_time, NULL); 00350 PQ.pkQueue.push_back(qp); 00351 00352 DEBUG(LOG_INFO, 0, "buffered pkt to %s qlen=%u", 00353 ip_to_str(dest_addr), PQ.length()); 00354 } 00355 00356 int NS_CLASS packet_queue_set_verdict(struct in_addr dest_addr, int verdict) 00357 { 00358 int count = 0; 00359 rt_table_t *rt, *next_hop_rt, *inet_rt = NULL; 00360 struct in_addr gw_addr; 00361 00362 double delay = 0; 00363 #define ARP_DELAY 0.005 00364 00365 if (verdict == PQ_ENC_SEND) 00366 { 00367 gw_addr.s_addr = ManetAddress(*gateWayAddress); 00368 rt = rt_table_find(gw_addr); 00369 } 00370 else 00371 rt = rt_table_find(dest_addr); 00372 00373 std::vector<ManetAddress> list; 00374 if (isInMacLayer()) 00375 { 00376 std::vector<MACAddress> listMac; 00377 getApList(dest_addr.s_addr.getMAC(),listMac); 00378 while (!listMac.empty()) 00379 { 00380 list.push_back(ManetAddress(listMac.back())); 00381 listMac.pop_back(); 00382 } 00383 } 00384 else 00385 { 00386 std::vector<IPv4Address> listIp; 00387 getApListIp(dest_addr.s_addr.getIPv4(),listIp); 00388 while (!listIp.empty()) 00389 { 00390 list.push_back(ManetAddress(listIp.back())); 00391 listIp.pop_back(); 00392 } 00393 } 00394 00395 while (!list.empty()) 00396 { 00397 struct in_addr dest_addr; 00398 dest_addr.s_addr = list.back(); 00399 list.pop_back(); 00400 for (unsigned int i=0; i < PQ.pkQueue.size();) 00401 { 00402 struct q_pkt *qp = PQ.pkQueue[i]; 00403 if (qp->dest_addr.s_addr == dest_addr.s_addr) 00404 { 00405 PQ.pkQueue.erase(PQ.pkQueue.begin()+i); 00406 switch (verdict) 00407 { 00408 case PQ_ENC_SEND: 00409 if (dynamic_cast <IPv4Datagram *> (qp->p)) 00410 { 00411 qp->p = pkt_encapsulate(dynamic_cast <IPv4Datagram *> (qp->p), *gateWayAddress); 00412 // now Ip layer decremented again 00413 /* Apparently, the link layer implementation can't handle a burst of packets. So to keep ARP happy, buffered 00414 * packets are sent with ARP_DELAY seconds between sends. */ 00415 sendDelayed(qp->p, delay, "to_ip"); 00416 delay += ARP_DELAY; 00417 } 00418 else 00419 { 00420 sendICMP(qp->p); 00421 } 00422 break; 00423 case PQ_SEND: 00424 if (!rt) 00425 return -1; 00426 /* Apparently, the link layer implementation can't handle 00427 * a burst of packets. So to keep ARP happy, buffered 00428 * packets are sent with ARP_DELAY seconds between 00429 * sends. */ 00430 // now Ip layer decremented again 00431 sendDelayed(qp->p, delay, "to_ip"); 00432 delay += ARP_DELAY; 00433 break; 00434 case PQ_DROP: 00435 sendICMP(qp->p); 00436 break; 00437 } 00438 free(qp); 00439 count++; 00440 } 00441 else 00442 i++; 00443 } 00444 } 00445 /* Update rt timeouts */ 00446 if (rt && rt->state == VALID && 00447 (verdict == PQ_SEND || verdict == PQ_ENC_SEND)) 00448 { 00449 if (dest_addr.s_addr != DEV_IFINDEX(rt->ifindex).ipaddr.s_addr) 00450 { 00451 if (verdict == PQ_ENC_SEND && inet_rt) 00452 rt_table_update_timeout(inet_rt, ACTIVE_ROUTE_TIMEOUT); 00453 00454 rt_table_update_timeout(rt, ACTIVE_ROUTE_TIMEOUT); 00455 00456 next_hop_rt = rt_table_find(rt->next_hop); 00457 00458 if (next_hop_rt && next_hop_rt->state == VALID && 00459 next_hop_rt->dest_addr.s_addr != rt->dest_addr.s_addr) 00460 rt_table_update_timeout(next_hop_rt, ACTIVE_ROUTE_TIMEOUT); 00461 } 00462 00463 DEBUG(LOG_INFO, 0, "SENT %d packets to %s qlen=%u", 00464 count, ip_to_str(dest_addr), PQ.length()); 00465 } 00466 else if (verdict == PQ_DROP) 00467 { 00468 DEBUG(LOG_INFO, 0, "DROPPED %d packets for %s!", 00469 count, ip_to_str(dest_addr)); 00470 } 00471 00472 return count; 00473 } 00474 00475 #endif