NETWORK ATTACKS FRAMEWORK  1.0.0
A NETwork Attacks framework. Making network attacks impact evaluation easier!
NA_packet_queue_omnet.cc
Go to the documentation of this file.
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
 All Classes Files Functions Variables Typedefs Enumerator Defines