NETWORK ATTACKS FRAMEWORK  1.0.0
A NETwork Attacks framework. Making network attacks impact evaluation easier!
NA_aodv_rerr.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 #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_rerr.h"
00035 #include "NA_routing_table.h"
00036 #include "NA_aodv_socket.h"
00037 #include "NA_aodv_timeout.h"
00038 #include "NA_defs_aodv.h"
00039 #include "NA_debug_aodv.h"
00040 #include "NA_params.h"
00041 #endif
00042 
00043 RERR *NS_CLASS rerr_create(u_int8_t flags,struct in_addr dest_addr,
00044                            u_int32_t dest_seqno)
00045 
00046 {
00047     RERR *rerr;
00048     DEBUG(LOG_DEBUG, 0, "Assembling RERR about %s seqno=%d",
00049           ip_to_str(dest_addr), dest_seqno);
00050 #ifndef OMNETPP
00051     rerr = (RERR *) aodv_socket_new_msg();
00052     rerr->dest_addr = dest_addr.s_addr;
00053     rerr->dest_seqno = htonl(dest_seqno);
00054 #else
00055     rerr = new RERR("RouteError");
00056     rerr->addUdest (dest_addr.s_addr,htonl(dest_seqno));
00057     totalRerrSend++;
00058 #endif
00059     rerr->type = AODV_RERR;
00060     rerr->n = (flags & RERR_NODELETE ? 1 : 0);
00061     rerr->res1 = 0;
00062     rerr->res2 = 0;
00063     rerr->dest_count = 1;
00064     return rerr;
00065 }
00066 
00067 void NS_CLASS rerr_add_udest(RERR * rerr,struct in_addr udest,
00068                              u_int32_t udest_seqno)
00069 {
00070 #ifndef OMNETPP
00071     RERR_udest *ud;
00072     ud = (RERR_udest *) ((char *) rerr + RERR_CALC_SIZE(rerr));
00073     ud->dest_addr = udest.s_addr;
00074     ud->dest_seqno = htonl(udest_seqno);
00075     rerr->dest_count++;
00076 #else
00077     rerr->addUdest( udest.s_addr, htonl(udest_seqno));
00078 #endif
00079 }
00080 
00081 
00082 void NS_CLASS rerr_process(RERR * rerr, int rerrlen,struct in_addr ip_src,
00083                            struct in_addr ip_dst)
00084 {
00085     RERR *new_rerr = NULL;
00086     RERR_udest *udest;
00087     rt_table_t *rt;
00088     u_int32_t rerr_dest_seqno;
00089     struct in_addr udest_addr, rerr_unicast_dest;
00090     int i;
00091     int numInterfaces;
00092 
00093     rerr_unicast_dest.s_addr = ManetAddress::ZERO;
00094 
00095     DEBUG(LOG_DEBUG, 0, "ip_src=%s", ip_to_str(ip_src));
00096 
00097     log_pkt_fields((AODV_msg *) rerr);
00098 
00099     if (rerrlen < ((int) RERR_CALC_SIZE(rerr)))
00100     {
00101         alog(LOG_WARNING, 0, __FUNCTION__,
00102              "IP data too short (%u bytes) from %s to %s. Should be %d bytes.",
00103              rerrlen, ip_to_str(ip_src), ip_to_str(ip_dst),
00104              RERR_CALC_SIZE(rerr));
00105         return;
00106     }
00107 
00108 
00109 #ifdef OMNETPP
00110     totalRerrRec++;
00111 #endif
00112 
00113     /* Check which destinations that are unreachable.  */
00114     udest = RERR_UDEST_FIRST(rerr);
00115 
00116     while (rerr->dest_count)
00117     {
00118 
00119         udest_addr.s_addr = udest->dest_addr;
00120         rerr_dest_seqno = ntohl(udest->dest_seqno);
00121         DEBUG(LOG_DEBUG, 0, "unreachable dest=%s seqno=%lu",
00122               ip_to_str(udest_addr), rerr_dest_seqno);
00123 
00124         rt = rt_table_find(udest_addr);
00125         if (rt && rt->state == VALID && rt->next_hop.s_addr == ip_src.s_addr)
00126         {
00127 
00128             /* Checking sequence numbers here is an out of draft
00129              *       * addition to AODV-UU. It is here because it makes a lot
00130              *       * of sense... */
00131             if (0 && (int32_t) rt->dest_seqno > (int32_t) rerr_dest_seqno)
00132             {
00133                 DEBUG(LOG_DEBUG, 0, "Udest ignored because of seqno");
00134                 udest = RERR_UDEST_NEXT(udest);
00135                 rerr->dest_count--;
00136                 continue;
00137             }
00138             DEBUG(LOG_DEBUG, 0, "removing rte %s - WAS IN RERR!!",
00139                   ip_to_str(udest_addr));
00140 
00141 #ifdef NS_PORT
00142 #ifndef OMNETPP
00143             interfaceQueue((nsaddr_t) udest_addr.s_addr, IFQ_DROP_BY_DEST);
00144 #endif
00145 #endif
00146             /* Invalidate route: */
00147             if (!rerr->n)
00148             {
00149                 rt_table_invalidate(rt);
00150             }
00151             /* (a) updates the corresponding destination sequence number
00152              *         with the Destination Sequence Number in the packet, and */
00153             rt->dest_seqno = rerr_dest_seqno;
00154 
00155             /* (d) check precursor list for emptiness. If not empty, include
00156              *         the destination as an unreachable destination in the
00157              *         RERR... */
00158             if (rt->nprec && !(rt->flags & RT_REPAIR))
00159             {
00160 
00161                 if (!new_rerr)
00162                 {
00163                     u_int8_t flags = 0;
00164 
00165                     if (rerr->n)
00166                         flags |= RERR_NODELETE;
00167 
00168                     new_rerr = rerr_create(flags, rt->dest_addr,
00169                                            rt->dest_seqno);
00170                     DEBUG(LOG_DEBUG, 0, "Added %s as unreachable, seqno=%lu",
00171                           ip_to_str(rt->dest_addr), rt->dest_seqno);
00172 #ifdef AODV_USE_STL_RT
00173                     if (rt->nprec == 1)
00174                         rerr_unicast_dest = rt->precursors[0].neighbor;
00175 #else
00176                     if (rt->nprec == 1)
00177                         rerr_unicast_dest =
00178                             FIRST_PREC(rt->precursors)->neighbor;
00179 #endif
00180                 }
00181                 else
00182                 {
00183                     /* Decide whether new precursors make this a non unicast RERR */
00184                     rerr_add_udest(new_rerr, rt->dest_addr, rt->dest_seqno);
00185 
00186 
00187                     DEBUG(LOG_DEBUG, 0, "Added %s as unreachable, seqno=%lu",
00188                           ip_to_str(rt->dest_addr), rt->dest_seqno);
00189 
00190 #ifdef AODV_USE_STL_RT
00191                     if (rerr_unicast_dest.s_addr.isUnspecified())
00192                     {
00193                         for (unsigned int i = 0; i< rt->precursors.size(); i++)
00194                         {
00195                             precursor_t *pr = & rt->precursors[i];
00196                             if (pr->neighbor.s_addr != rerr_unicast_dest.s_addr)
00197                             {
00198                                 rerr_unicast_dest.s_addr = ManetAddress::ZERO;
00199                                 break;
00200                             }
00201                         }
00202                     }
00203 #else
00204                     if (rerr_unicast_dest.s_addr)
00205                     {
00206                         list_t *pos2;
00207                         list_foreach(pos2, &rt->precursors)
00208                         {
00209                             precursor_t *pr = (precursor_t *) pos2;
00210                             if (pr->neighbor.s_addr != rerr_unicast_dest.s_addr)
00211                             {
00212                                 rerr_unicast_dest.s_addr = 0;
00213                                 break;
00214                             }
00215                         }
00216                     }
00217 #endif
00218                 }
00219             }
00220             else
00221             {
00222                 DEBUG(LOG_DEBUG, 0,
00223                       "Not sending RERR, no precursors or route in RT_REPAIR");
00224             }
00225             /* We should delete the precursor list for all unreachable
00226              *         destinations. */
00227             if (rt->state == INVALID)
00228                 precursor_list_destroy(rt);
00229         }
00230         else
00231         {
00232             DEBUG(LOG_DEBUG, 0, "Ignoring UDEST %s", ip_to_str(udest_addr));
00233         }
00234         udest = RERR_UDEST_NEXT(udest);
00235         rerr->dest_count--;
00236     }               /* End while() */
00237 #ifdef OMNETPP
00238     if (rerr->dest_count==0)
00239         rerr->clearUdest();
00240 #endif
00241 
00242     /* If a RERR was created, then send it now... */
00243     if (new_rerr)
00244     {
00245         rt = rt_table_find(rerr_unicast_dest);
00246         new_rerr->ttl=1;
00247 
00248         if (rt && new_rerr->dest_count == 1 && !rerr_unicast_dest.s_addr.isUnspecified())
00249             aodv_socket_send((AODV_msg *) new_rerr,
00250                              rerr_unicast_dest,
00251                              RERR_CALC_SIZE(new_rerr), 1,
00252                              &DEV_IFINDEX(rt->ifindex));
00253 
00254         else if (new_rerr->dest_count > 0)
00255         {
00256             /* FIXME: Should only transmit RERR on those interfaces
00257              * which have precursor nodes for the broken route */
00258             numInterfaces = 0;
00259             for (i = 0; i < MAX_NR_INTERFACES; i++)
00260             {
00261                 if (!DEV_NR(i).enabled)
00262                     continue;
00263                 numInterfaces++;
00264             }
00265 
00266             for (i = 0; i < MAX_NR_INTERFACES; i++)
00267             {
00268                 struct in_addr dest;
00269 
00270                 if (!DEV_NR(i).enabled)
00271                     continue;
00272                 dest.s_addr = ManetAddress(IPv4Address(AODV_BROADCAST));
00273 #ifdef OMNETPP
00274                 if (numInterfaces>1)
00275                 {
00276                     aodv_socket_send((AODV_msg *) new_rerr->dup(), dest,RERR_CALC_SIZE(new_rerr), 1, &DEV_NR(i));
00277                 }
00278                 else
00279 #endif
00280                     aodv_socket_send((AODV_msg *) new_rerr, dest,RERR_CALC_SIZE(new_rerr), 1, &DEV_NR(i));
00281                 numInterfaces--;
00282             }
00283 
00284         }
00285     }
00286 }
00287 
 All Classes Files Functions Variables Typedefs Enumerator Defines