00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <string.h>
00033 #include <netinet/in.h>
00034 #include "aodv.h"
00035
00036
00037
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
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
00711
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
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
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 }