handle_message.c

00001 /* Copyright 2008 Michael Marsh, University of Maryland.
00002  *
00003  * This file is part of pydtn.
00004  *
00005  * pydtn 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 3 of the License, or
00008  * (at your option) any later version.
00009  *
00010  * pydtn 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 pydtn.  If not, see <http://www.gnu.org/licenses/>.
00017  *
00018  * The views and conclusions contained in the software and documentation
00019  * are those of the authors and should not be interpreted as representing
00020  * official policies, either expressed or implied, of the University
00021  * of Maryland.
00022  *
00023  * pydtn extends and embeds the Python interpreter, which is
00024  * Copyright 2001-2006 Python Software Foundation, All Rights Reserved,
00025  * and is released under the PSF License Agreement.
00026  *
00027  * RANLUX random number generation uses the Boost library,
00028  * Copyright 1994-2006 by various authors (details in individual files),
00029  * which is released under the Boost Software License, Version 1.0.
00030  */
00031 
00032 #include <string.h>
00033 #include <netinet/in.h>
00034 #include "aodv.h"
00035 
00036 /*
00037  * Internal routines.
00038  */
00039 
00040 static int
00041 _copy_path( aodv_node_list_t** dst, aodv_node_list_t* src )
00042 {
00043    aodv_node_list_t* dcurr = NULL;
00044    aodv_node_list_t* dhead = NULL;
00045    aodv_node_list_t* dtail = NULL;
00046    aodv_node_list_t* scurr = src;
00047    aodv_node_list_t* shead = src;
00048 
00049    if ( NULL == src )
00050    {
00051       return 1;
00052    }
00053 
00054    dhead = (aodv_node_list_t*) malloc( sizeof(aodv_node_list_t) );
00055    if ( NULL == dhead )
00056    {
00057       return 0;
00058    }
00059    dhead->node.data = NULL;
00060    dhead->node.length = 0U;
00061    set_aodv_addr( &(dhead->node), &(shead->node) );
00062    dhead->seq  = shead->seq;
00063    dhead->next = dhead;
00064    dhead->prev = dhead;
00065    dtail = dhead;
00066    scurr = scurr->next;
00067    for ( ; scurr != shead ; scurr = scurr->next )
00068    {
00069       dcurr = (aodv_node_list_t*) malloc( sizeof(aodv_node_list_t) );
00070       if ( NULL == dcurr )
00071       {
00072          free_aodv_node_list( dhead );
00073          return 0;
00074       }
00075       dcurr->prev = dtail;
00076       dcurr->next = dhead;
00077       dtail->next = dcurr;
00078       dhead->prev = dcurr;
00079       dtail = dcurr;
00080 
00081       dcurr->node.data = NULL;
00082       dcurr->node.length = 0U;
00083       set_aodv_addr( &(dcurr->node), &(scurr->node) );
00084       dcurr->seq  = scurr->seq;
00085    }
00086 
00087    *dst = dhead;
00088    return 1;
00089 }
00090 
00091 static aodv_rrep_t*
00092 _generate_rrep( aodv_state_t* state,
00093                 const aodv_rreq_t* request,
00094                 const aodv_table_entry_t* entry )
00095 {
00096    aodv_rrep_t* retval;
00097 
00098    if ( ( 0 != aodv_cmp_addr( &(request->destination), &(state->self) ) ) &&
00099         ( NULL == entry ) )
00100    {
00101       return NULL;
00102    }
00103 
00104    retval = (aodv_rrep_t*) malloc( sizeof( aodv_rrep_t ) );
00105    if ( NULL == retval )
00106    {
00107       return retval;
00108    }
00109 
00110    retval->destination.addr.data = NULL;
00111    retval->destination.addr.length = 0U;
00112    set_aodv_addr( &(retval->destination.addr) , &(request->destination) );
00113    retval->originator.data = NULL;
00114    retval->originator.length = 0U;
00115    set_aodv_addr( &(retval->originator) , &(request->originator) );
00116    retval->orig_seq = request->orig_seq;
00117    retval->ack_flag = state->use_acks;
00118    retval->apn_count = request->hop_count - 1;
00119    retval->path = NULL;
00120    if ( ! _copy_path( &(retval->path), request->path ) )
00121    {
00122       free_aodv_rrep( retval );
00123       return NULL;
00124    }
00125    if ( 0 == aodv_cmp_addr( &(request->destination), &(state->self) ) )
00126    {
00127       retval->hop_count = 0;
00128       retval->destination.prefix = state->subnet_size;
00129       if ( aodv_cmp_seq( request->dest_seq, state->sequence_number ) > 0 )
00130       {
00131          state->sequence_number = request->dest_seq;
00132          aodv_incr_seq( state );
00133       }
00134       retval->dest_seq = state->sequence_number;
00135    }
00136    else
00137    {
00138       retval->hop_count = entry->hop_count;
00139       retval->destination.prefix = entry->destination.prefix;
00140       retval->dest_seq = entry->dest_seq;
00141    }
00142 
00143    aodv_log_rrep_c( state, retval );
00144 
00145    return retval;
00146 }
00147 
00148 static aodv_rreq_t*
00149 _unserialize_rreq( const aodv_chunk_t* message )
00150 {
00151    aodv_rreq_t* request;
00152    unsigned char* pData;
00153    unsigned int length;
00154    unsigned char i;
00155    uint8_t  b;
00156    uint16_t s;
00157    uint32_t l;
00158 
00159    if ( NULL == message )
00160    {
00161       return NULL;
00162    }
00163 
00164    length = message->length;
00165 
00166    request = (aodv_rreq_t*) malloc( sizeof( aodv_rreq_t ) );
00167    if ( NULL == request )
00168    {
00169       return NULL;
00170    }
00171 
00172    pData = message->data;
00173 
00174    request->next = NULL;
00175    request->prev = NULL;
00176    request->path = NULL;
00177    request->buffer_time.tv_sec = -1;
00178    request->buffer_time.tv_usec = 0;
00179 
00180    if ( ! aodv_get8( &pData, &length, &b ) )
00181    {
00182       free_aodv_rreq(request);
00183       return NULL;
00184    }
00185 
00186    if ( ! aodv_get16( &pData, &length, &s ) )
00187    {
00188       free_aodv_rreq(request);
00189       return NULL;
00190    }
00191    request->dest_only_flag = ( ntohs(s) & kAodvRreqD ) ? 1 : 0;
00192    request->grat_rrep_flag = ( ntohs(s) & kAodvRreqG ) ? 1 : 0;
00193 
00194    if ( ! aodv_get8( &pData, &length, &b ) )
00195    {
00196       free_aodv_rreq(request);
00197       return NULL;
00198    }
00199    request->hop_count = b;
00200 
00201    if ( ! aodv_get32( &pData, &length, &l ) )
00202    {
00203       free_aodv_rreq(request);
00204       return NULL;
00205    }
00206    request->rreq_id = ntohl(l);
00207 
00208    if ( ! aodv_get_addr( &pData, &length, &(request->destination) ) )
00209    {
00210       free_aodv_rreq(request);
00211       return NULL;
00212    }
00213 
00214    if ( ! aodv_get32( &pData, &length, &l ) )
00215    {
00216       free_aodv_rreq(request);
00217       return NULL;
00218    }
00219    request->dest_seq = ntohl(l);
00220 
00221    if ( ! aodv_get_addr( &pData, &length, &(request->originator) ) )
00222    {
00223       free_aodv_rreq(request);
00224       return NULL;
00225    }
00226 
00227    if ( ! aodv_get32( &pData, &length, &l ) )
00228    {
00229       free_aodv_rreq(request);
00230       return NULL;
00231    }
00232    request->orig_seq = ntohl(l);
00233 
00234    for ( i = 0 ; i < request->hop_count - 1 ; ++i )
00235    {
00236       aodv_addr_t addr;
00237       uint32_t seq;
00238 
00239       if ( ! aodv_get_addr( &pData, &length, &addr ) )
00240       {
00241          free_aodv_rreq(request);
00242          return NULL;
00243       }
00244 
00245       if ( ! aodv_get32( &pData, &length, &l ) )
00246       {
00247          free_aodv_rreq(request);
00248          return NULL;
00249       }
00250       seq = ntohl(l);
00251 
00252       if ( ! aodv_add_to_node_list( &(request->path), &addr, seq ) )
00253       {
00254          free_aodv_rreq(request);
00255          return NULL;
00256       }
00257    }
00258 
00259    return request;
00260 }
00261 
00262 
00263 static int
00264 _handle_rreq( aodv_state_t* state,
00265               const aodv_msghdr_t* hdrs,
00266               const aodv_chunk_t* message )
00267 {
00268    aodv_rreq_t* rreq = _unserialize_rreq( message );
00269    aodv_rrep_t* rrep;
00270 
00271    aodv_table_entry_t*  entry;
00272    aodv_table_entry_t*  oentry;
00273 
00274    aodv_node_list_t   originator;
00275    aodv_node_list_t*  ncurr;;
00276 
00277    if ( NULL == rreq ) return 0;
00278 
00279    rreq->ttl = hdrs->ttl;
00280    aodv_log_rreq_r( state, rreq, hdrs );
00281 
00282    if ( 0 == aodv_cmp_addr( &(rreq->originator), &(state->self) ) )
00283    {
00284       free_aodv_rreq( rreq );
00285       return 1;
00286    }
00287 
00288    ++(rreq->hop_count);
00289 
00290    originator.next = NULL;
00291    originator.prev = NULL;
00292    originator.node.data = NULL;
00293    originator.node.length = 0U;
00294    set_aodv_addr( &(originator.node), &(rreq->originator) );
00295    originator.seq  = rreq->orig_seq;
00296    oentry =
00297       update_aodv_table_entry( state, hdrs, &originator, rreq->hop_count );
00298    if ( NULL == oentry )
00299    {
00300       free_aodv_rreq( rreq );
00301       return 0;
00302    }
00303    ncurr = rreq->path;
00304    if ( NULL != ncurr )
00305    {
00306       unsigned char hops = rreq->hop_count;
00307       do
00308       {
00309          --hops;
00310          if ( NULL == update_aodv_table_entry( state, hdrs, ncurr, hops ) )
00311          {
00312             free_aodv_rreq( rreq );
00313             return 0;
00314          }
00315          ncurr = ncurr->next;
00316       } while ( ( ncurr != rreq->path ) && ( hops > 0 ) );
00317    }
00318 
00319    if ( is_buffered_rcvd_aodv_rreq( state, rreq ) )
00320    {
00321       free_aodv_rreq( rreq );
00322       return 1;
00323    }
00324    buffer_rcvd_aodv_rreq( state, rreq );
00325 
00326    if ( 0 == aodv_cmp_addr( &(rreq->destination), &(state->self) ) )
00327    {
00328       rrep = _generate_rrep( state, rreq, NULL );
00329       if ( NULL == rrep ) return 0;
00330       aodv_unicast_rrep( state, rrep );
00331       free_aodv_rrep( rrep );
00332       return 1;
00333    }
00334 
00335    if ( ! aodv_add_to_node_list( &(rreq->path),
00336                                  &(state->self),
00337                                  state->sequence_number ) )
00338    {
00339       return 0;
00340    }
00341 
00342    entry = aodv_lookup( &(state->routing_table), &(rreq->destination) );
00343 
00344    if ( NULL != entry )
00345    {
00346       if ( aodv_cmp_seq( entry->dest_seq, rreq->dest_seq ) > 0 )
00347       {
00348          rreq->dest_seq = entry->dest_seq;
00349       }
00350 
00351       if ( entry->valid_route && (! rreq->dest_only_flag) )
00352       {
00353          rrep = _generate_rrep( state, rreq, entry );
00354          if ( NULL == rrep ) return 0;
00355          aodv_unicast_rrep( state, rrep );
00356          free_aodv_rrep( rrep );
00357          if ( rreq->grat_rrep_flag )
00358          {
00359             aodv_rrep_t  grrep;
00360             grrep.path = NULL;
00361             grrep.ack_flag = state->use_acks;
00362             grrep.apn_count = 0;
00363             grrep.hop_count = rreq->hop_count;
00364             grrep.destination.addr.data = NULL;
00365             grrep.destination.addr.length = 0U;
00366             set_aodv_addr( &(grrep.destination.addr), &(rreq->originator) );
00367             grrep.destination.prefix = 0;
00368             grrep.dest_seq = rreq->orig_seq;
00369             grrep.originator.data = NULL;
00370             grrep.originator.length = 0U;
00371             set_aodv_addr( &(grrep.originator), &(rreq->destination) );
00372             grrep.orig_seq = rreq->dest_seq;
00373             aodv_unicast_rrep( state, &grrep );
00374          }
00375          return 1;
00376       }
00377    }
00378 
00379    if ( rreq->ttl <= 1 )
00380    {
00381       return 1;
00382    }
00383    --(rreq->ttl);
00384 
00385    aodv_bcast_rreq( state, rreq );
00386 
00387    return 0;
00388 }
00389 
00390 static aodv_rrep_t*
00391 _unserialize_rrep( const aodv_chunk_t* message )
00392 {
00393    aodv_rrep_t* response;
00394    unsigned char* pData;
00395    unsigned int length;
00396    unsigned char i;
00397    uint8_t  b;
00398    uint16_t s;
00399    uint32_t l;
00400    uint16_t temp16;
00401 
00402    if ( NULL == message )
00403    {
00404       return NULL;
00405    }
00406 
00407    length = message->length;
00408    if ( length < k_aodv_rrep_min_len )
00409    {
00410       return NULL;
00411    }
00412 
00413    response = (aodv_rrep_t*) malloc( sizeof( aodv_rrep_t ) );
00414    if ( NULL == response )
00415    {
00416       return NULL;
00417    }
00418 
00419    pData = message->data;
00420 
00421    response->path = NULL;
00422 
00423    if ( ! aodv_get8( &pData, &length, &b ) )
00424    {
00425       free_aodv_rrep(response);
00426       return NULL;
00427    }
00428 
00429    if ( ! aodv_get16( &pData, &length, &s ) )
00430    {
00431       free_aodv_rrep(response);
00432       return NULL;
00433    }
00434    temp16 = ntohs(s);
00435    response->ack_flag = ( temp16 & kAodvRrepA ) ? 1 : 0;
00436    response->destination.prefix = 0;
00437    for ( i = 0 ; i < 5 ; ++i, temp16 >>= 1 )
00438    {
00439       if ( temp16 & 1 )
00440       {
00441          response->destination.prefix &= ( 1 << i );
00442       }
00443    }
00444    response->apn_count = 0;
00445    for ( i = 0 ; i < 5 ; ++i, temp16 >>= 1 )
00446    {
00447       if ( temp16 & 1 )
00448       {
00449          response->apn_count &= ( 1 << i );
00450       }
00451    }
00452 
00453    if ( ! aodv_get8( &pData, &length, &b ) )
00454    {
00455       free_aodv_rrep(response);
00456       return NULL;
00457    }
00458    response->hop_count = b;
00459 
00460    if ( ! aodv_get_addr( &pData, &length, &(response->destination.addr) ) )
00461    {
00462       free_aodv_rrep(response);
00463       return NULL;
00464    }
00465 
00466    if ( ! aodv_get32( &pData, &length, &l ) )
00467    {
00468       free_aodv_rrep(response);
00469       return NULL;
00470    }
00471    response->dest_seq = ntohl(l);
00472 
00473    if ( ! aodv_get_addr( &pData, &length, &(response->originator) ) )
00474    {
00475       free_aodv_rrep(response);
00476       return NULL;
00477    }
00478 
00479    if ( ! aodv_get32( &pData, &length, &l ) )
00480    {
00481       free_aodv_rrep(response);
00482       return NULL;
00483    }
00484    response->orig_seq = ntohl(l);
00485 
00486    for ( i = 0 ; i < response->apn_count ; ++i )
00487    {
00488       aodv_addr_t addr;
00489       uint32_t   seq;
00490 
00491       if ( ! aodv_get_addr( &pData, &length, &addr ) )
00492       {
00493          free_aodv_rrep(response);
00494          return NULL;
00495       }
00496 
00497       if ( ! aodv_get32( &pData, &length, &l ) )
00498       {
00499          free_aodv_rrep(response);
00500          return NULL;
00501       }
00502       seq = ntohl(l);
00503 
00504       if ( ! aodv_add_to_node_list( &(response->path), &addr, seq ) )
00505       {
00506          free_aodv_rrep(response);
00507          return NULL;
00508       }
00509    }
00510 
00511    return response;
00512 }
00513 
00514 static int
00515 _handle_rrep( aodv_state_t* state,
00516               const aodv_msghdr_t* hdrs,
00517               const aodv_chunk_t* message )
00518 {
00519    aodv_rrep_t* rrep = _unserialize_rrep( message );
00520    aodv_table_entry_t* entry;
00521    aodv_node_list_t  nl;
00522    aodv_node_list_t* ncurr;
00523    unsigned char update = 0;
00524    char cmp;
00525 
00526    if ( NULL == rrep ) return 0;
00527 
00528    aodv_log_rrep_r( state, rrep, hdrs );
00529 
00530    ++(rrep->hop_count);
00531 
00532    nl.node.data = NULL;
00533    nl.node.length = 0U;
00534    set_aodv_addr( &(nl.node), &(rrep->destination.addr) );
00535    nl.seq  = rrep->dest_seq;
00536    entry = update_aodv_table_entry( state, hdrs, &nl, rrep->hop_count );
00537    if ( NULL == entry )
00538    {
00539       free_aodv_rrep( rrep );
00540       return 0;
00541    }
00542    entry->destination.prefix = rrep->destination.prefix;
00543    aodv_route_notify( state, &(entry->destination.addr) );
00544 
00545    ncurr = rrep->path;
00546    if ( NULL != ncurr )
00547    {
00548       unsigned char hops = rrep->hop_count;
00549       do
00550       {
00551          --hops;
00552          if ( NULL == update_aodv_table_entry( state, hdrs, ncurr, hops ) )
00553          {
00554             free_aodv_rrep( rrep );
00555             return 0;
00556          }
00557          aodv_route_notify( state, &(ncurr->node) );
00558          ncurr = ncurr->next;
00559       } while ( ( ncurr != rrep->path ) && ( hops > 0 ) );
00560    }
00561 
00562    if ( rrep->ack_flag )
00563    {
00564       aodv_unicast_rrep_ack( state, hdrs );
00565    }
00566 
00567    if ( 0 == aodv_cmp_addr( &(rrep->destination.addr), &(state->self) ) )
00568    {
00569       free_aodv_rrep( rrep );
00570       return 1;
00571    }
00572 
00573    if ( 0 == aodv_cmp_addr( &(rrep->originator), &(state->self) ) )
00574    {
00575       aodv_rreq_t* rreq =
00576          find_buffered_aodv_rreq( state, &(rrep->destination.addr) );
00577       if ( NULL != rreq )
00578       {
00579          unbuffer_aodv_rreq( state, rreq );
00580       }
00581    }
00582    else
00583    {
00584       aodv_unicast_rrep( state, rrep );
00585    }
00586 
00587    free_aodv_rrep( rrep );
00588 
00589    return 1;
00590 }
00591 
00592 static aodv_rerr_t*
00593 _unserialize_rerr( const aodv_chunk_t* message )
00594 {
00595    aodv_rerr_t* retval;
00596    unsigned char* pData;
00597    unsigned int length;
00598    unsigned char i;
00599    uint8_t  b;
00600    uint16_t s;
00601    uint32_t l;
00602 
00603    if ( NULL == message )
00604    {
00605       return NULL;
00606    }
00607 
00608    length = message->length;
00609    if ( length < k_aodv_rerr_min_len )
00610    {
00611       return NULL;
00612    }
00613 
00614    retval = (aodv_rerr_t*) malloc( sizeof( aodv_rerr_t ) );
00615    if ( NULL == retval )
00616    {
00617       return NULL;
00618    }
00619 
00620    pData = message->data;
00621 
00622    retval->unreachable = NULL;
00623 
00624    if ( ! aodv_get8( &pData, &length, &b ) )
00625    {
00626       free_aodv_rerr(retval);
00627       return NULL;
00628    }
00629 
00630    if ( ! aodv_get16( &pData, &length, &s ) )
00631    {
00632       free_aodv_rerr(retval);
00633       return NULL;
00634    }
00635 
00636    if ( ! aodv_get8( &pData, &length, &b ) )
00637    {
00638       free_aodv_rerr(retval);
00639       return NULL;
00640    }
00641    retval->dest_count = b;
00642 
00643    for ( i = 0 ; i < retval->dest_count ; ++i )
00644    {
00645       aodv_addr_t addr;
00646       uint32_t   seq;
00647 
00648       if ( ! aodv_get_addr( &pData, &length, &addr ) )
00649       {
00650          free_aodv_rerr(retval);
00651          return NULL;
00652       }
00653 
00654       if ( ! aodv_get32( &pData, &length, &l ) )
00655       {
00656          free_aodv_rerr(retval);
00657          return NULL;
00658       }
00659       seq = ntohl(l);
00660 
00661       if ( ! aodv_add_to_node_list( &(retval->unreachable), &addr, seq ) )
00662       {
00663          free_aodv_rerr(retval);
00664          return NULL;
00665       }
00666    }
00667 
00668    return retval;
00669 }
00670 
00671 static int
00672 _handle_rerr( aodv_state_t* state,
00673               const aodv_msghdr_t* hdrs,
00674               const aodv_chunk_t* message )
00675 {
00676    aodv_rerr_t* rerr = _unserialize_rerr( message );
00677    aodv_table_entry_t* eroute;
00678    aodv_table_entry_t* uroute;
00679    aodv_node_list_t* uhead;
00680    aodv_node_list_t* ucurr;
00681    aodv_rerr_t newerr;
00682    unsigned int gen_rerr = 0;
00683    char cmp;
00684 
00685    if ( NULL == rerr ) return 0;
00686 
00687    aodv_log_rerr_r( state, rerr, hdrs );
00688 
00689    /*
00690     * First create a route to the sender, if there isn't one.
00691     */
00692    eroute = aodv_lookup( &(state->routing_table), &(hdrs->addr) );
00693    if ( NULL == eroute )
00694    {
00695       eroute = add_aodv_table_entry( &(state->routing_table),
00696                                      &(hdrs->addr),
00697                                      0 );
00698       if ( NULL != eroute )
00699       {
00700          aodv_update_route_expiry( state, eroute );
00701          eroute->dest_seq = 0;
00702          set_aodv_addr( &(eroute->next_hop), &(hdrs->addr) );
00703          eroute->hop_count = 1;
00704          eroute->interface = hdrs->interface;
00705          eroute->valid_route = 1;
00706       }
00707    }
00708 
00709    /*
00710     * Now look for routes to invalidate, adding them to a new RERR message
00711     * if appropriate.
00712     */
00713    newerr.dest_count = 0;
00714    newerr.unreachable = NULL;
00715    uhead = rerr->unreachable;
00716    ucurr = uhead;
00717    if ( uhead )
00718    {
00719       do
00720       {
00721          uroute = aodv_lookup( &(state->routing_table), &(ucurr->node) );
00722          if ( NULL != uroute )
00723          {
00724             cmp = aodv_cmp_seq( ucurr->seq, uroute->dest_seq );
00725             if ( ( 0 == aodv_cmp_addr(&(uroute->next_hop), &(hdrs->addr)) ) &&
00726                  uroute->valid_route &&
00727                  ( ( 0 == ucurr->seq ) || ( cmp > 0 ) ) )
00728             {
00729                gen_rerr = 1;
00730                newerr.dest_count++;
00731                aodv_add_to_node_list( &(newerr.unreachable),
00732                                          &(uroute->destination.addr),
00733                                          uroute->dest_seq );
00734                uroute->valid_route = 0;
00735                if ( cmp > 0 )
00736                {
00737                   uroute->dest_seq = ucurr->seq;
00738                }
00739             }
00740          }
00741          ucurr = ucurr->next;
00742       } while ( ucurr != uhead );
00743    }
00744 
00745    /*
00746     * Send the new RERR message, if needed.
00747     */
00748    if ( gen_rerr )
00749    {
00750       if (  aodv_insert_time( state->rerr_time_ring ) )
00751       {
00752          aodv_bcast_rerr( state, &(newerr) );
00753       }
00754    }
00755 
00756    return 1;
00757 }
00758 
00759 static int
00760 _handle_rrep_ack( aodv_state_t* state,
00761                   const aodv_msghdr_t* hdrs,
00762                   const aodv_chunk_t* message )
00763 {
00764    aodv_log_rrep_ack_r( state, hdrs );
00765    return 0;
00766 }
00767 
00768 
00769 /*
00770  * Entry point.
00771  */
00772 
00773 int
00774 aodv_handle_message( aodv_state_t* state,
00775                      const aodv_msghdr_t* hdrs,
00776                      const aodv_chunk_t* message )
00777 {
00778    int retval = 0;
00779 
00780    aodv_chunk_t* msg;
00781 
00782    if ( NULL == state )
00783    {
00784       return retval;
00785    }
00786 
00787    msg = collapse_chunk( message );
00788    if ( NULL == msg )
00789    {
00790       return retval;
00791    }
00792 
00793    if ( msg->length < 1 )
00794    {
00795       free_aodv_chunk(msg);
00796       return retval;
00797    }
00798 
00799    switch( msg->data[0] )
00800    {
00801       case 1 :
00802          retval = _handle_rreq(state,hdrs,msg);
00803          break;
00804       case 2 :
00805          retval = _handle_rrep(state,hdrs,msg);
00806          break;
00807       case 3 :
00808          retval = _handle_rerr(state,hdrs,msg);
00809          break;
00810       case 4 :
00811          retval = _handle_rrep_ack(state,hdrs,msg);
00812          break;
00813       default :
00814          retval = 0;
00815    }
00816 
00817    free_aodv_chunk(msg);
00818    return retval;
00819 }

Generated on Mon Mar 24 11:15:45 2008 for Pydtn Simulator by  doxygen 1.5.4