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 <netinet/in.h>
00033 #include <string.h>
00034 #include "aodv.h"
00035
00036 static int
00037 _put8( unsigned char** pData, unsigned int* pLength, uint8_t b )
00038 {
00039 if ( *pLength < 1 )
00040 {
00041 return 0;
00042 }
00043 if ( NULL == pData )
00044 {
00045 return 0;
00046 }
00047 if ( NULL == *pData )
00048 {
00049 return 0;
00050 }
00051
00052 (*pData)[0] = b;
00053 *pData += 1;
00054 *pLength -= 1;
00055 return 1;
00056 }
00057
00058 static int
00059 _put16( unsigned char** pData, unsigned int* pLength, uint16_t s )
00060 {
00061 unsigned char* data;
00062 union
00063 {
00064 uint16_t s;
00065 unsigned char c[2];
00066 } temp;
00067
00068 if ( *pLength < 2 )
00069 {
00070 return 0;
00071 }
00072 if ( NULL == pData )
00073 {
00074 return 0;
00075 }
00076 if ( NULL == *pData )
00077 {
00078 return 0;
00079 }
00080 data = *pData;
00081
00082 temp.s = s;
00083 data[0] = temp.c[0];
00084 data[1] = temp.c[1];
00085
00086 *pData += 2;
00087 *pLength -= 2;
00088 return 1;
00089 }
00090
00091 static int
00092 _put32( unsigned char** pData, unsigned int* pLength, uint32_t l )
00093 {
00094 unsigned char* data;
00095 union
00096 {
00097 uint32_t l;
00098 unsigned char c[4];
00099 } temp;
00100
00101 if ( *pLength < 4 )
00102 {
00103 return 0;
00104 }
00105 if ( NULL == pData )
00106 {
00107 return 0;
00108 }
00109 if ( NULL == *pData )
00110 {
00111 return 0;
00112 }
00113 data = *pData;
00114
00115 temp.l = l;
00116 data[0] = temp.c[0];
00117 data[1] = temp.c[1];
00118 data[2] = temp.c[2];
00119 data[3] = temp.c[3];
00120
00121 *pData += 4;
00122 *pLength -= 4;
00123 return 1;
00124 }
00125
00126 static int
00127 _put_addr( unsigned char** pData, unsigned int* pLength, const aodv_addr_t* a )
00128 {
00129 if ( NULL == pData ) return 0;
00130 if ( NULL == *pData ) return 0;
00131 if ( NULL == pLength ) return 0;
00132 if ( NULL == a ) return 0;
00133 if ( NULL == a->data ) return 0;
00134 if ( 0 == a->length ) return 0;
00135 if ( *pLength < (2+a->length) ) return 0;
00136
00137 _put16( pData, pLength, htons(a->length) );
00138 memcpy( *pData, a->data, a->length );
00139 *pData += a->length;
00140 *pLength -= a->length;
00141
00142 return 1;
00143 }
00144
00145 static aodv_chunk_t*
00146 _serialize_rreq( const aodv_rreq_t* rreq )
00147 {
00148 unsigned char* pData;
00149 aodv_chunk_t* retval = NULL;
00150 aodv_chunk_t* tail;
00151 aodv_node_list_t* ncurr;
00152 unsigned int length;
00153 uint16_t flags = 0;
00154
00155
00156 length = 1 + sizeof(uint16_t) + sizeof(unsigned char) + sizeof(uint32_t);
00157 retval = new_aodv_chunk( length );
00158 if ( NULL == retval )
00159 {
00160 return NULL;
00161 }
00162 pData = retval->data;
00163 _put8( &pData, &length, 1 );
00164
00165 if ( rreq->dest_only_flag) flags |= kAodvRreqD;
00166 if ( rreq->grat_rrep_flag) flags |= kAodvRreqG;
00167 _put16( &pData, &length, htons(flags) );
00168 _put8( &pData, &length, rreq->hop_count );
00169 _put32( &pData, &length, htonl(rreq->rreq_id) );
00170 tail = retval;
00171
00172
00173 length =
00174 sizeof(uint16_t) +
00175 rreq->destination.length*sizeof(unsigned char) +
00176 sizeof(uint32_t);
00177 tail->next = new_aodv_chunk( length );
00178 if ( NULL == tail->next )
00179 {
00180 return NULL;
00181 }
00182 tail = tail->next;
00183 pData = tail->data;
00184 _put_addr(&pData,&length,&(rreq->destination));
00185 _put32(&pData,&length,htonl(rreq->dest_seq));
00186
00187
00188 length =
00189 sizeof(uint16_t) +
00190 rreq->originator.length*sizeof(unsigned char) +
00191 sizeof(uint32_t);
00192 tail->next = new_aodv_chunk( length );
00193 if ( NULL == tail->next )
00194 {
00195 return NULL;
00196 }
00197 tail = tail->next;
00198 pData = tail->data;
00199 _put_addr(&pData,&length,&(rreq->originator));
00200 _put32(&pData,&length,htonl(rreq->orig_seq));
00201
00202
00203 ncurr = rreq->path;
00204 if ( NULL != ncurr )
00205 {
00206 do
00207 {
00208 length =
00209 sizeof(uint16_t) +
00210 ncurr->node.length*sizeof(unsigned char) +
00211 sizeof(uint32_t);
00212 tail->next = new_aodv_chunk( length );
00213 if ( NULL == tail->next )
00214 {
00215 return NULL;
00216 }
00217 tail = tail->next;
00218 pData = tail->data;
00219 _put_addr(&pData,&length,&(ncurr->node));
00220 _put32(&pData,&length,htonl(ncurr->seq));
00221 ncurr = ncurr->next;
00222 } while ( ncurr != rreq->path );
00223 }
00224
00225
00226 tail = retval;
00227 retval = collapse_chunk( tail );
00228
00229 return retval;
00230 }
00231
00238 void
00239 aodv_bcast_rreq( aodv_state_t* state, const aodv_rreq_t* request )
00240 {
00241 aodv_chunk_t* msg;
00242 aodv_msghdr_t hdrs;
00243 unsigned int i;
00244
00245 if ( NULL == state ) return;
00246 if ( NULL == state->interfaces.interfaces ) return;
00247
00248 aodv_set_bcast_addr( &(hdrs.addr) );
00249 hdrs.ttl = state->params.net_diameter;
00250
00251 msg = _serialize_rreq( request );
00252 if ( NULL == msg ) return;
00253
00254 aodv_log_rreq_s( state, request, &hdrs );
00255
00256 for ( i = 0 ; i < state->interfaces.nifaces ; ++i )
00257 {
00258 hdrs.interface = state->interfaces.interfaces[i];
00259 aodv_send_message( state, &hdrs, msg );
00260 }
00261
00262 free_aodv_chunk( msg );
00263 }
00264
00265
00266 static aodv_chunk_t*
00267 _serialize_rrep( const aodv_rrep_t* rrep )
00268 {
00269 unsigned char* pData;
00270 aodv_chunk_t* retval = NULL;
00271 aodv_node_list_t* ncurr;
00272 unsigned int length = k_aodv_rrep_min_len;
00273 uint16_t flags = 0;
00274 unsigned int i;
00275
00276 length += rrep->destination.addr.length + rrep->originator.length;
00277 ncurr = rrep->path;
00278 if ( NULL != ncurr )
00279 {
00280 do
00281 {
00282 length += 6 + ncurr->node.length;
00283 ncurr = ncurr->next;
00284 } while ( ncurr != rrep->path );
00285 }
00286
00287 retval = new_aodv_chunk( length );
00288 if ( NULL == retval )
00289 {
00290 return NULL;
00291 }
00292
00293 pData = retval->data;
00294 _put8( &pData, &length, 2 );
00295
00296 if ( rrep->ack_flag) flags |= kAodvRrepA;
00297 for ( i = 0 ; i < 5 ; ++i )
00298 {
00299 if (rrep->destination.prefix & (1<<i))
00300 {
00301 flags |= (1 << i);
00302 }
00303 if (rrep->apn_count & (1<<i))
00304 {
00305 flags |= (1 << (i+5));
00306 }
00307 }
00308 _put16( &pData, &length, htons(flags) );
00309
00310 _put8( &pData, &length, rrep->hop_count );
00311
00312 _put_addr( &pData, &length, &(rrep->destination.addr) );
00313 _put32( &pData, &length, htonl(rrep->dest_seq) );
00314 _put_addr( &pData, &length, &(rrep->originator) );
00315 _put32( &pData, &length, htonl(rrep->orig_seq) );
00316
00317 ncurr = rrep->path;
00318 if ( NULL != ncurr )
00319 {
00320 do
00321 {
00322 _put_addr( &pData, &length, &(ncurr->node) );
00323 _put32( &pData, &length, htonl(ncurr->seq) );
00324 ncurr = ncurr->next;
00325 } while ( ncurr != rrep->path );
00326 }
00327
00328 return retval;
00329 }
00330
00337 void
00338 aodv_unicast_rrep( aodv_state_t* state, const aodv_rrep_t* response )
00339 {
00340 aodv_chunk_t* msg;
00341 aodv_msghdr_t hdrs;
00342
00343 const aodv_node_list_t* selfnode;
00344 aodv_table_entry_t* next_hop;
00345
00346 if ( NULL == state ) return;
00347 if ( NULL == response ) return;
00348
00349 hdrs.addr.data = NULL;
00350 hdrs.addr.length = 0U;
00351
00352 selfnode = aodv_find_in_node_list( response->path, &(state->self) );
00353 if ( ( NULL == selfnode ) ||
00354 ( selfnode == selfnode->prev ) )
00355 {
00356 next_hop = aodv_lookup( &(state->routing_table),
00357 &(response->originator) );
00358 if ( NULL == next_hop ) return;
00359 set_aodv_addr( &(hdrs.addr), &(next_hop->next_hop) );
00360 hdrs.interface = next_hop->interface;
00361 }
00362 else
00363 {
00364 set_aodv_addr( &(hdrs.addr), &(selfnode->prev->node) );
00365 next_hop = aodv_lookup( &(state->routing_table), &(hdrs.addr) );
00366 if ( NULL == next_hop ) return;
00367 hdrs.interface = next_hop->interface;
00368 }
00369 hdrs.ttl = state->params.net_diameter;
00370
00371 msg = _serialize_rrep( response );
00372 if ( NULL == msg ) return;
00373
00374 aodv_log_rrep_s( state, response, &hdrs );
00375
00376 aodv_send_message( state, &hdrs, msg );
00377
00378 free_aodv_chunk( msg );
00379 }
00380
00381 static aodv_chunk_t*
00382 _serialize_rerr( const aodv_rerr_t* rerr )
00383 {
00384 unsigned char* pData;
00385 aodv_chunk_t* retval = NULL;
00386 aodv_node_list_t* ncurr;
00387 unsigned int length = k_aodv_rerr_min_len;
00388 unsigned char ucount = 0;
00389
00390 ncurr = rerr->unreachable;
00391 if ( NULL != ncurr )
00392 {
00393 do
00394 {
00395 ++ucount;
00396 length += 6 + ncurr->node.length;
00397 ncurr = ncurr->next;
00398 } while ( ncurr != rerr->unreachable );
00399 }
00400
00401 if ( ucount != rerr->dest_count )
00402 {
00403 return NULL;
00404 }
00405
00406 retval = new_aodv_chunk( length );
00407 if ( NULL == retval )
00408 {
00409 return NULL;
00410 }
00411
00412 pData = retval->data;
00413 _put8( &pData, &length, 3 );
00414 _put16( &pData, &length, 0 );
00415 _put8( &pData, &length, rerr->dest_count );
00416
00417 ncurr = rerr->unreachable;
00418 if ( NULL != ncurr )
00419 {
00420 do
00421 {
00422 _put_addr( &pData, &length, &(ncurr->node) );
00423 _put32( &pData, &length, htonl(ncurr->seq) );
00424 ncurr = ncurr->next;
00425 } while ( ncurr != rerr->unreachable );
00426 }
00427
00428 return retval;
00429 }
00430
00437 void
00438 aodv_bcast_rerr( aodv_state_t* state, const aodv_rerr_t* rerr )
00439 {
00440 aodv_chunk_t* msg;
00441 aodv_msghdr_t hdrs;
00442 unsigned int i;
00443
00444 if ( NULL == state ) return;
00445 if ( NULL == state->interfaces.interfaces ) return;
00446
00447 aodv_set_bcast_addr( &(hdrs.addr) );
00448 hdrs.ttl = 1;
00449
00450 msg = _serialize_rerr( rerr );
00451 if ( NULL == msg ) return;
00452
00453 aodv_log_rerr_s( state, rerr, &hdrs );
00454
00455 for ( i = 0 ; i < state->interfaces.nifaces ; ++i )
00456 {
00457 hdrs.interface = state->interfaces.interfaces[i];
00458 aodv_send_message( state, &hdrs, msg );
00459 }
00460
00461 free_aodv_chunk( msg );
00462 }
00463
00464 static aodv_chunk_t*
00465 _serialize_rrep_ack()
00466 {
00467 unsigned char* pData;
00468 aodv_chunk_t* retval = NULL;
00469 unsigned int length = k_aodv_rrep_ack_len;
00470
00471 retval = new_aodv_chunk( length );
00472 if ( NULL == retval )
00473 {
00474 return NULL;
00475 }
00476
00477 pData = retval->data;
00478 _put8( &pData, &length, 4 );
00479 _put8( &pData, &length, 0 );
00480
00481 return retval;
00482 }
00483
00490 void
00491 aodv_unicast_rrep_ack( aodv_state_t* state,
00492 const aodv_msghdr_t* inhdrs )
00493 {
00494 aodv_chunk_t* msg;
00495 aodv_msghdr_t hdrs;
00496
00497 if ( NULL == state ) return;
00498 if ( NULL == inhdrs ) return;
00499
00500 hdrs.addr.length = 0;
00501 hdrs.addr.data = NULL;
00502 set_aodv_addr( &(hdrs.addr), &(inhdrs->addr) );
00503
00504 hdrs.interface = inhdrs->interface;
00505 hdrs.ttl = 1;
00506
00507 msg = _serialize_rrep_ack();
00508 if ( NULL == msg ) return;
00509
00510 aodv_log_rrep_ack_s( state, &hdrs );
00511
00512 aodv_send_message( state, &hdrs, msg );
00513
00514 free_aodv_chunk( msg );
00515 }
00516