Aodv Patch

31
 aodv.cc Go to the documentation of this file. 00001 /* 00002 Copyright (c) 1997, 1998 Carnegie Mellon University. All Rights 00003 Reserved. 00004 00005 Redistribution and use in source and binary forms, with or without 00006 modification, are permitted provided that the following conditions are met: 00007 00008 1. Redistributions of source code must retain the above copyright notice, 00009 this list of conditions and the following disclaimer. 00010 2. Redistributions in binary form must reproduce the above copyright notice, 00011 this list of conditions and the following disclaimer in the documentation 00012 and/or other materials provided with the distribution. 00013 3. The name of the author may not be used to endorse or promote products 00014 derived from this software without specific prior written permission. 00015 00016 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 00017 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00018 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 00019 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00020 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00021 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 00022 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 00023 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 00024 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 00025 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00026 00027 The AODV code developed by the CMU/MONARCH group was optimized and tuned by Samir Das and Mahesh Marina, University of Cincinnati. The work was partially done in Sun Microsystems. Modified for gratuitous replies by Anant Utgikar, 09/16/02. 00028 00029 */ 00030

Transcript of Aodv Patch

Page 1: Aodv Patch

5/14/2018 Aodv Patch - slidepdf.com

http://slidepdf.com/reader/full/aodv-patch 1/31

 

aodv.cc

Go to the documentation of this file.

00001 /*

00002 Copyright (c) 1997, 1998 Carnegie Mellon University. All Rights00003 Reserved.

00004

00005 Redistribution and use in source and binary forms, with or without

00006 modification, are permitted provided that the following conditionsare met:

00007

00008 1. Redistributions of source code must retain the above copyrightnotice,

00009 this list of conditions and the following disclaimer.

00010 2. Redistributions in binary form must reproduce the above

copyright notice,00011 this list of conditions and the following disclaimer in thedocumentation

00012 and/or other materials provided with the distribution.

00013 3. The name of the author may not be used to endorse or promoteproducts

00014 derived from this software without specific prior writtenpermission.

00015

00016 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSOR

00017 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIEDWARRANTIES

00018 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AREDISCLAIMED.

00019 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,INCIDENTAL,

00020 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOTLIMITED TO,

00021 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, ORPROFITS;

00022 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY,

00023 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDINGNEGLIGENCE OR

00024 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,EVEN IF

00025 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

00026

00027 The AODV code developed by the CMU/MONARCH group was optimized andtuned by Samir Das and Mahesh Marina, University of Cincinnati. The workwas partially done in Sun Microsystems. Modified for gratuitous repliesby Anant Utgikar, 09/16/02.

00028

00029 */00030

Page 2: Aodv Patch

5/14/2018 Aodv Patch - slidepdf.com

http://slidepdf.com/reader/full/aodv-patch 2/31

 

00031 //#include <ip.h>

00032

00033 #include <aodv/aodv.h>

00034 #include <aodv/aodv_packet.h>

00035 #include <random.h>

00036 #include <cmu-trace.h>

00037 //#include <energy-model.h>

00038

00039 #define max(a,b) ( (a) > (b) ? (a) : (b) )

00040 #define CURRENT_TIME Scheduler::instance().clock()

00041

00042 //#define DEBUG

00043 //#define ERROR

00044

00045 #ifdef DEBUG

00046 static int extra_route_reply = 0;00047 static int limit_route_request = 0;

00048 static int route_request = 0;

00049 #endif

00050

00051

00052 /*

00053 TCL Hooks

00054 */

00055

0005600057 int hdr_aodv::offset_;

00058 static class AODVHeaderClass : public PacketHeaderClass {

00059 public:

00060  AODVHeaderClass() : PacketHeaderClass("PacketHeader/AODV",

00061sizeof(hdr_all_aodv)) {

00062 bind_offset(&hdr_aodv::offset_);

00063 }

00064 } class_rtProtoAODV_hdr;

00065

00066 static class AODVclass : public TclClass {

00067 public:

00068  AODVclass() : TclClass("Agent/AODV") {}

00069  TclObject* create(int argc, const char*const* argv) {

00070 assert(argc == 5);

00071 //return (new AODV((nsaddr_t) atoi(argv[4])));

00072 return (new AODV((nsaddr_t)Address::instance().str2addr(argv[4])));

00073 }

00074 } class_rtProtoAODV;

0007500076

Page 3: Aodv Patch

5/14/2018 Aodv Patch - slidepdf.com

http://slidepdf.com/reader/full/aodv-patch 3/31

 

00077 int

00078 AODV::command(int argc, const char*const* argv) {

00079 if(argc == 2) {

00080 Tcl& tcl = Tcl::instance();

00081

00082 if(strncasecmp(argv[1], "id", 2) == 0) {

00083 tcl.resultf("%d", index);

00084 return TCL_OK;

00085 }

00086

00087 if(strncasecmp(argv[1], "start", 2) == 0) {

00088 btimer.handle((Event*) 0);

00089

00090 #ifndef AODV_LINK_LAYER_DETECTION

00091 htimer.handle((Event*) 0);

00092 ntimer.handle((Event*) 0);00093 #endif // LINK LAYER DETECTION

00094

00095 rtimer.handle((Event*) 0);

00096 return TCL_OK;

00097 }

00098 }

00099 else if(argc == 3) {

00100 if(strcmp(argv[1], "index") == 0) {

00101 index = atoi(argv[2]);

00102 return TCL_OK;00103 }

00104

00105 else if(strcmp(argv[1], "log-target") == 0 || strcmp(argv[1],"tracetarget") == 0) {

00106 logtarget = (Trace*) TclObject::lookup(argv[2]);

00107 if(logtarget == 0)

00108 return TCL_ERROR;

00109 return TCL_OK;

00110 }

00111 else if(strcmp(argv[1], "drop-target") == 0) {

00112 int stat = rqueue.command(argc,argv);

00113 if (stat != TCL_OK) return stat;

00114 return Agent::command(argc, argv);

00115 }

00116 else if(strcmp(argv[1], "if-queue") == 0) {

00117 ifqueue = (PriQueue*) TclObject::lookup(argv[2]);

00118

00119 if(ifqueue == 0)

00120 return TCL_ERROR;

00121 return TCL_OK;

00122 }00123 else if (strcmp(argv[1], "port-dmux") == 0) {

Page 4: Aodv Patch

5/14/2018 Aodv Patch - slidepdf.com

http://slidepdf.com/reader/full/aodv-patch 4/31

 

00124 dmux_ = (PortClassifier *)TclObject::lookup(argv[2]);

00125 if (dmux_ == 0) {

00126 fprintf (stderr, "%s: %s lookup of %s failed\n", __FILE__,

00127 argv[1], argv[2]);

00128 return TCL_ERROR;

00129 }

00130 return TCL_OK;

00131 }

00132 }

00133 return Agent::command(argc, argv);

00134 }

00135

00136 /*

00137 Constructor

00138 */

0013900140 AODV::AODV(nsaddr_t id) : Agent(PT_AODV),

00141 btimer(this), htimer(this), ntimer(this),

00142 rtimer(this), lrtimer(this), rqueue() {

00143

00144

00145 index = id;

00146 seqno = 2;

00147 bid = 1;

00148

00149 LIST_INIT(&nbhead);00150 LIST_INIT(&bihead);

00151

00152 logtarget = 0;

00153 ifqueue = 0;

00154 }

00155

00156 /*

00157 Timers

00158 */

00159

00160 void

00161 BroadcastTimer::handle(Event*) {

00162 agent->id_purge();

00163 Scheduler::instance().schedule(this, &intr, BCAST_ID_SAVE);

00164 }

00165

00166 void

00167 HelloTimer::handle(Event*) {

00168 agent->sendHello();

00169 double interval = MinHelloInterval +

00170 ((MaxHelloInterval - MinHelloInterval) *Random::uniform());

Page 5: Aodv Patch

5/14/2018 Aodv Patch - slidepdf.com

http://slidepdf.com/reader/full/aodv-patch 5/31

 

00171 assert(interval >= 0);

00172 Scheduler::instance().schedule(this, &intr, interval);

00173 }

00174

00175 void

00176 NeighborTimer::handle(Event*) {

00177 agent->nb_purge();

00178 Scheduler::instance().schedule(this, &intr, HELLO_INTERVAL);

00179 }

00180

00181 void

00182 RouteCacheTimer::handle(Event*) {

00183 agent->rt_purge();

00184 #define FREQUENCY 0.5 // sec

00185 Scheduler::instance().schedule(this, &intr, FREQUENCY);

00186 }00187

00188 void

00189 LocalRepairTimer::handle(Event* p) { // SRD: 5/4/99

00190 aodv_rt_entry *rt;

00191 struct hdr_ip *ih = HDR_IP( (Packet *)p);

00192

00193 /* you get here after the timeout in a local repair attempt */

00194 /* fprintf(stderr, "%s\n", __FUNCTION__); */

00195

0019600197 rt = agent->rtable.rt_lookup(ih->daddr());

00198

00199 if (rt && rt->rt_flags != RTF_UP) {

00200 // route is yet to be repaired

00201 // I will be conservative and bring down the route

00202 // and send route errors upstream.

00203 /* The following assert fails, not sure why */

00204 /* assert (rt->rt_flags == RTF_IN_REPAIR); */

00205

00206 //rt->rt_seqno++;

00207 agent->rt_down(rt);

00208 // send RERR

00209 #ifdef DEBUG

00210 fprintf(stderr,"Node %d: Dst - %d, failed localrepair\n",index, rt->rt_dst);

00211 #endif

00212 }

00213 Packet::free((Packet *)p);

00214 }

00215

0021600217 /*

Page 6: Aodv Patch

5/14/2018 Aodv Patch - slidepdf.com

http://slidepdf.com/reader/full/aodv-patch 6/31

 

00218 Broadcast ID Management Functions

00219 */

00220

00221

00222 void

00223 AODV::id_insert(nsaddr_t id, u_int32_t bid) {

00224 BroadcastID *b = new BroadcastID(id, bid);

00225

00226 assert(b);

00227 b->expire = CURRENT_TIME + BCAST_ID_SAVE;

00228 LIST_INSERT_HEAD(&bihead, b, link);

00229 }

00230

00231 /* SRD */

00232 bool

00233 AODV::id_lookup(nsaddr_t id, u_int32_t bid) {00234 BroadcastID *b = bihead.lh_first;

00235

00236 // Search the list for a match of source and bid

00237 for( ; b; b = b->link.le_next) {

00238 if ((b->src == id) && (b->id == bid))

00239 return true;

00240 }

00241 return false;

00242 }

0024300244 void

00245 AODV::id_purge() {

00246 BroadcastID *b = bihead.lh_first;

00247 BroadcastID *bn;

00248 double now = CURRENT_TIME;

00249

00250 for(; b; b = bn) {

00251 bn = b->link.le_next;

00252 if(b->expire <= now) {

00253 LIST_REMOVE(b,link);

00254 delete b;

00255 }

00256 }

00257 }

00258

00259 /*

00260 Helper Functions

00261 */

00262

00263 double

00264 AODV::PerHopTime(aodv_rt_entry *rt) {00265 int num_non_zero = 0, i;

Page 7: Aodv Patch

5/14/2018 Aodv Patch - slidepdf.com

http://slidepdf.com/reader/full/aodv-patch 7/31

 

00266 double total_latency = 0.0;

00267

00268 if (!rt)

00269 return ((double) NODE_TRAVERSAL_TIME );

00270

00271 for (i=0; i < MAX_HISTORY; i++) {

00272 if (rt->rt_disc_latency[i] > 0.0) {

00273 num_non_zero++;

00274 total_latency += rt->rt_disc_latency[i];

00275 }

00276 }

00277 if (num_non_zero > 0)

00278 return(total_latency / (double) num_non_zero);

00279 else

00280 return((double) NODE_TRAVERSAL_TIME);

0028100282 }

00283

00284 /*

00285 Link Failure Management Functions

00286 */

00287

00288 static void

00289 aodv_rt_failed_callback(Packet *p, void *arg) {

00290 ((AODV*) arg)->rt_ll_failed(p);

00291 }00292

00293 /*

00294 * This routine is invoked when the link-layer reports a routefailed.

00295 */

00296 void

00297 AODV::rt_ll_failed(Packet *p) {

00298 struct hdr_cmn *ch = HDR_CMN(p);

00299 struct hdr_ip *ih = HDR_IP(p);

00300 aodv_rt_entry *rt;

00301 nsaddr_t broken_nbr = ch->next_hop_;

00302

00303 #ifndef AODV_LINK_LAYER_DETECTION

00304 drop(p, DROP_RTR_MAC_CALLBACK);

00305 #else

00306

00307 /*

00308 * Non-data packets and Broadcast Packets can be dropped.

00309 */

00310 if(! DATA_PACKET(ch->ptype()) ||

00311 (u_int32_t) ih->daddr() == IP_BROADCAST) {00312 drop(p, DROP_RTR_MAC_CALLBACK);

Page 8: Aodv Patch

5/14/2018 Aodv Patch - slidepdf.com

http://slidepdf.com/reader/full/aodv-patch 8/31

 

00313 return;

00314 }

00315 log_link_broke(p);

00316 if((rt = rtable.rt_lookup(ih->daddr())) == 0) {

00317 drop(p, DROP_RTR_MAC_CALLBACK);

00318 return;

00319 }

00320 log_link_del(ch->next_hop_);

00321

00322 #ifdef AODV_LOCAL_REPAIR

00323 /* if the broken link is closer to the dest than source,

00324 attempt a local repair. Otherwise, bring down the route. */

00325

00326

00327 if (ch->num_forwards() > rt->rt_hops) {

00328 local_rt_repair(rt, p); // local repair00329 // retrieve all the packets in the ifq using this link,

00330 // queue the packets for which local repair is done,

00331 return;

00332 }

00333 else 

00334 #endif // LOCAL REPAIR

00335

00336 {

00337 drop(p, DROP_RTR_MAC_CALLBACK);

00338 // Do the same thing for other packets in the interface queueusing the

00339 // broken link -Mahesh

00340 while((p = ifqueue->filter(broken_nbr))) {

00341 drop(p, DROP_RTR_MAC_CALLBACK);

00342 }

00343 nb_delete(broken_nbr);

00344 }

00345

00346 #endif // LINK LAYER DETECTION

00347 }

00348

00349 void

00350 AODV::handle_link_failure(nsaddr_t id) {

00351 aodv_rt_entry *rt, *rtn;

00352 Packet *rerr = Packet::alloc();

00353 struct hdr_aodv_error *re = HDR_AODV_ERROR(rerr);

00354

00355 re->DestCount = 0;

00356 for(rt = rtable.head(); rt; rt = rtn) { // for each rt entry

00357 rtn = rt->rt_link.le_next;

00358 if ((rt->rt_hops != INFINITY2) && (rt->rt_nexthop == id) ) {00359 assert (rt->rt_flags == RTF_UP);

Page 9: Aodv Patch

5/14/2018 Aodv Patch - slidepdf.com

http://slidepdf.com/reader/full/aodv-patch 9/31

 

00360 assert((rt->rt_seqno%2) == 0);

00361 rt->rt_seqno++;

00362 re->unreachable_dst[re->DestCount] = rt->rt_dst;

00363 re->unreachable_dst_seqno[re->DestCount] = rt->rt_seqno;

00364 #ifdef DEBUG

00365 fprintf(stderr, "%s(%f): %d\t(%d\t%u\t%d)\n", __FUNCTION__,CURRENT_TIME,

00366 index, re->unreachable_dst[re->DestCount],

00367 re->unreachable_dst_seqno[re->DestCount], rt->rt_nexthop);

00368 #endif // DEBUG

00369 re->DestCount += 1;

00370 rt_down(rt);

00371 }

00372 // remove the lost neighbor from all the precursor lists

00373 rt->pc_delete(id);

00374 }

00375

00376 if (re->DestCount > 0) {

00377 #ifdef DEBUG

00378 fprintf(stderr, "%s(%f): %d\tsending RERR...\n", __FUNCTION__,CURRENT_TIME, index);

00379 #endif // DEBUG

00380 sendError(rerr, false);

00381 }

00382 else {

00383 Packet::free(rerr);00384 }

00385 }

00386

00387 void

00388 AODV::local_rt_repair(aodv_rt_entry *rt, Packet *p) {

00389 #ifdef DEBUG

00390 fprintf(stderr,"%s: Dst - %d\n", __FUNCTION__, rt->rt_dst);

00391 #endif

00392 // Buffer the packet

00393 rqueue.enque(p);00394

00395 // mark the route as under repair

00396 rt->rt_flags = RTF_IN_REPAIR;

00397

00398 sendRequest(rt->rt_dst);

00399

00400 // set up a timer interrupt

00401 Scheduler::instance().schedule(&lrtimer, p->copy(), rt->rt_req_timeout);

00402 }

00403

00404 void

Page 10: Aodv Patch

5/14/2018 Aodv Patch - slidepdf.com

http://slidepdf.com/reader/full/aodv-patch 10/31

 

00405 AODV::rt_update(aodv_rt_entry *rt, u_int32_t seqnum, u_int16_t metric,

00406 nsaddr_t nexthop, double expire_time) {

00407

00408 rt->rt_seqno = seqnum;

00409 rt->rt_hops = metric;

00410 rt->rt_flags = RTF_UP;

00411 rt->rt_nexthop = nexthop;

00412 rt->rt_expire = expire_time;

00413 }

00414

00415 void

00416 AODV::rt_down(aodv_rt_entry *rt) {

00417 /*

00418 * Make sure that you don't "down" a route more than once.

00419 */00420

00421 if(rt->rt_flags == RTF_DOWN) {

00422 return;

00423 }

00424

00425 // assert (rt->rt_seqno%2); // is the seqno odd?

00426 rt->rt_last_hop_count = rt->rt_hops;

00427 rt->rt_hops = INFINITY2;

00428 rt->rt_flags = RTF_DOWN;

00429 rt->rt_nexthop = 0;

00430 rt->rt_expire = 0;

00431

00432 } /* rt_down function */

00433

00434 /*

00435 Route Handling Functions

00436 */

00437

00438 void

00439 AODV::rt_resolve(Packet *p) {

00440 struct hdr_cmn *ch = HDR_CMN(p);

00441 struct hdr_ip *ih = HDR_IP(p);

00442 aodv_rt_entry *rt;

00443

00444 /*

00445 * Set the transmit failure callback. That

00446 * won't change.

00447 */

00448 ch->xmit_failure_ = aodv_rt_failed_callback;

00449 ch->xmit_failure_data_ = (void*) this;

00450 rt = rtable.rt_lookup(ih->daddr());00451 if(rt == 0) {

Page 11: Aodv Patch

5/14/2018 Aodv Patch - slidepdf.com

http://slidepdf.com/reader/full/aodv-patch 11/31

 

00452 rt = rtable.rt_add(ih->daddr());

00453 }

00454

00455 /*

00456 * If the route is up, forward the packet

00457 */

00458

00459 if(rt->rt_flags == RTF_UP) {

00460 assert(rt->rt_hops != INFINITY2);

00461 forward(rt, p, NO_DELAY);

00462 }

00463 /*

00464 * if I am the source of the packet, then do a Route Request.

00465 */

00466 else if(ih->saddr() == index) {

00467 rqueue.enque(p);00468 sendRequest(rt->rt_dst);

00469 }

00470 /*

00471 * A local repair is in progress. Buffer the packet.

00472 */

00473 else if (rt->rt_flags == RTF_IN_REPAIR) {

00474 rqueue.enque(p);

00475 }

00476

00477 /*00478 * I am trying to forward a packet for someone else to which

00479 * I don't have a route.

00480 */

00481 else {

00482 Packet *rerr = Packet::alloc();

00483 struct hdr_aodv_error *re = HDR_AODV_ERROR(rerr);

00484 /*

00485 * For now, drop the packet and send error upstream.

00486 * Now the route errors are broadcast to upstream

00487 * neighbors - Mahesh 09/11/99

00488 */ 

00489

00490 assert (rt->rt_flags == RTF_DOWN);

00491 re->DestCount = 0;

00492 re->unreachable_dst[re->DestCount] = rt->rt_dst;

00493 re->unreachable_dst_seqno[re->DestCount] = rt->rt_seqno;

00494 re->DestCount += 1;

00495 #ifdef DEBUG

00496 fprintf(stderr, "%s: sending RERR...\n", __FUNCTION__);

00497 #endif

00498 sendError(rerr, false);00499

Page 12: Aodv Patch

5/14/2018 Aodv Patch - slidepdf.com

http://slidepdf.com/reader/full/aodv-patch 12/31

 

00500 drop(p, DROP_RTR_NO_ROUTE);

00501 }

00502

00503 }

00504

00505 void

00506 AODV::rt_purge() {

00507 aodv_rt_entry *rt, *rtn;

00508 double now = CURRENT_TIME;

00509 double delay = 0.0;

00510 Packet *p;

00511

00512 for(rt = rtable.head(); rt; rt = rtn) { // for each rt entry

00513 rtn = rt->rt_link.le_next;

00514 if ((rt->rt_flags == RTF_UP) && (rt->rt_expire < now)) {

00515 // if a valid route has expired, purge all packets from00516 // send buffer and invalidate the route.

00517 assert(rt->rt_hops != INFINITY2);

00518 while((p = rqueue.deque(rt->rt_dst))) {

00519 #ifdef DEBUG

00520 fprintf(stderr, "%s: calling drop()\n",

00521 __FUNCTION__);

00522 #endif // DEBUG

00523 drop(p, DROP_RTR_NO_ROUTE);

00524 }

00525 rt->rt_seqno++;00526 assert (rt->rt_seqno%2);

00527 rt_down(rt);

00528 }

00529 else if (rt->rt_flags == RTF_UP) {

00530 // If the route is not expired,

00531 // and there are packets in the sendbuffer waiting,

00532 // forward them. This should not be needed, but this extra

00533 // check does no harm.

00534 assert(rt->rt_hops != INFINITY2);

00535 while((p = rqueue.deque(rt->rt_dst))) {

00536 forward (rt, p, delay);

00537 delay += ARP_DELAY;

00538 }

00539 }

00540 else if (rqueue.find(rt->rt_dst))

00541 // If the route is down and

00542 // if there is a packet for this destination waiting in

00543 // the sendbuffer, then send out route request. sendRequest

00544 // will check whether it is time to really send out request

00545 // or not.

00546 // This may not be crucial to do it here, as each generated00547 // packet will do a sendRequest anyway.

Page 13: Aodv Patch

5/14/2018 Aodv Patch - slidepdf.com

http://slidepdf.com/reader/full/aodv-patch 13/31

 

00548

00549 sendRequest(rt->rt_dst);

00550 }

00551

00552 }

00553

00554 /*

00555 Packet Reception Routines

00556 */

00557

00558 void

00559 AODV::recv(Packet *p, Handler*) {

00560 struct hdr_cmn *ch = HDR_CMN(p);

00561 struct hdr_ip *ih = HDR_IP(p);

00562

00563 assert(initialized());00564 //assert(p->incoming == 0);

00565 // XXXXX NOTE: use of incoming flag has been depracated; In orderto track direction of pkt flow, direction_ in hdr_cmn is used instead.see packet.h for details.

00566

00567 if(ch->ptype() == PT_AODV) {

00568 ih->ttl_ -= 1;

00569 recvAODV(p);

00570 return;

00571 }

00572

00573

00574 /*

00575 * Must be a packet I'm originating...

00576 */

00577 if((ih->saddr() == index) && (ch->num_forwards() == 0)) {

00578 /*

00579 * Add the IP Header

00580 */

00581 ch->size() += IP_HDR_LEN;

00582 // Added by Parag Dadhania && John Novatnack to handlebroadcasting

00583 if ( (u_int32_t)ih->daddr() != IP_BROADCAST)

00584 ih->ttl_ = NETWORK_DIAMETER;

00585 }

00586 /*

00587 * I received a packet that I sent. Probably

00588 * a routing loop.

00589 */

00590 else if(ih->saddr() == index) {

00591 drop(p, DROP_RTR_ROUTE_LOOP);

00592 return;

Page 14: Aodv Patch

5/14/2018 Aodv Patch - slidepdf.com

http://slidepdf.com/reader/full/aodv-patch 14/31

 

00593 }

00594 /*

00595 * Packet I'm forwarding...

00596 */

00597 else {

00598 /*

00599 * Check the TTL. If it is zero, then discard.

00600 */

00601 if(--ih->ttl_ == 0) {

00602 drop(p, DROP_RTR_TTL);

00603 return;

00604 }

00605 }

00606 // Added by Parag Dadhania && John Novatnack to handlebroadcasting

00607 if ( (u_int32_t)ih->daddr() != IP_BROADCAST)00608 rt_resolve(p);

00609 else

00610 forward((aodv_rt_entry*) 0, p, NO_DELAY);

00611 }

00612

00613

00614 void

00615 AODV::recvAODV(Packet *p) {

00616 struct hdr_aodv *ah = HDR_AODV(p);

00617

00618 assert(HDR_IP (p)->sport() == RT_PORT);

00619 assert(HDR_IP (p)->dport() == RT_PORT);

00620

00621 /*

00622 * Incoming Packets.

00623 */

00624 switch(ah->ah_type) {

00625

00626 case AODVTYPE_RREQ:

00627 recvRequest(p);

00628 break;

00629

00630 case AODVTYPE_RREP:

00631 recvReply(p);

00632 break;

00633

00634 case AODVTYPE_RERR:

00635 recvError(p);

00636 break;

00637

00638 case AODVTYPE_HELLO:00639 recvHello(p);

Page 15: Aodv Patch

5/14/2018 Aodv Patch - slidepdf.com

http://slidepdf.com/reader/full/aodv-patch 15/31

 

00640 break;

00641

00642 default:

00643 fprintf(stderr, "Invalid AODV type (%x)\n", ah->ah_type);

00644 exit(1);

00645 }

00646

00647 }

00648

00649

00650 void

00651 AODV::recvRequest(Packet *p) {

00652 struct hdr_ip *ih = HDR_IP(p);

00653 struct hdr_aodv_request *rq = HDR_AODV_REQUEST(p);

00654 aodv_rt_entry *rt;

0065500656 /*

00657 * Drop if:

00658 * - I'm the source

00659 * - I recently heard this request.

00660 */

00661

00662 if(rq->rq_src == index) {

00663 #ifdef DEBUG

00664 fprintf(stderr, "%s: got my own REQUEST\n", __FUNCTION__);

00665 #endif // DEBUG00666 Packet::free(p);

00667 return;

00668 }

00669

00670 if (id_lookup(rq->rq_src, rq->rq_bcast_id)) {

00671

00672 #ifdef DEBUG

00673 fprintf(stderr, "%s: discarding request\n", __FUNCTION__);

00674 #endif // DEBUG

00675

00676 Packet::free(p);

00677 return;

00678 }

00679

00680 /*

00681 * Cache the broadcast ID

00682 */

00683 id_insert(rq->rq_src, rq->rq_bcast_id);

00684

00685

0068600687 /*

Page 16: Aodv Patch

5/14/2018 Aodv Patch - slidepdf.com

http://slidepdf.com/reader/full/aodv-patch 16/31

 

00688 * We are either going to forward the REQUEST or generate a

00689 * REPLY. Before we do anything, we make sure that the REVERSE

00690 * route is in the route table.

00691 */

00692 aodv_rt_entry *rt0; // rt0 is the reverse route

00693

00694 rt0 = rtable.rt_lookup(rq->rq_src);

00695 if(rt0 == 0) { /* if not in the route table */

00696 // create an entry for the reverse route.

00697 rt0 = rtable.rt_add(rq->rq_src);

00698 }

00699

00700 rt0->rt_expire = max(rt0->rt_expire, (CURRENT_TIME +REV_ROUTE_LIFE));

00701

00702 if ( (rq->rq_src_seqno > rt0->rt_seqno ) ||00703 ((rq->rq_src_seqno == rt0->rt_seqno) &&

00704 (rq->rq_hop_count < rt0->rt_hops)) ) {

00705 // If we have a fresher seq no. or lesser #hops for the

00706 // same seq no., update the rt entry. Else don't bother.

00707 rt_update(rt0, rq->rq_src_seqno, rq->rq_hop_count, ih->saddr(),

00708 max(rt0->rt_expire, (CURRENT_TIME +REV_ROUTE_LIFE)) );

00709 if (rt0->rt_req_timeout > 0.0) {

00710 // Reset the soft state and

00711 // Set expiry time to CURRENT_TIME + ACTIVE_ROUTE_TIMEOUT

00712 // This is because route is used in the forward direction,

00713 // but only sources get benefited by this change

00714 rt0->rt_req_cnt = 0;

00715 rt0->rt_req_timeout = 0.0;

00716 rt0->rt_req_last_ttl = rq->rq_hop_count;

00717 rt0->rt_expire = CURRENT_TIME + ACTIVE_ROUTE_TIMEOUT;

00718 }

00719

00720 /* Find out whether any buffered packet can benefit from the

00721 * reverse route.

00722 * May need some change in the following code - Mahesh09/11/99

00723 */

00724 assert (rt0->rt_flags == RTF_UP);

00725 Packet *buffered_pkt;

00726 while ((buffered_pkt = rqueue.deque(rt0->rt_dst))) {

00727 if (rt0 && (rt0->rt_flags == RTF_UP)) {

00728 assert(rt0->rt_hops != INFINITY2);

00729 forward(rt0, buffered_pkt, NO_DELAY);

00730 }

00731 }

00732 }

Page 17: Aodv Patch

5/14/2018 Aodv Patch - slidepdf.com

http://slidepdf.com/reader/full/aodv-patch 17/31

 

00733 // End for putting reverse route in rt table

00734

00735

00736 /*

00737 * We have taken care of the reverse route stuff.

00738 * Now see whether we can send a route reply.

00739 */

00740

00741 rt = rtable.rt_lookup(rq->rq_dst);

00742

00743 // First check if I am the destination ..

00744

00745 if(rq->rq_dst == index) {

00746

00747 #ifdef DEBUG

00748 fprintf(stderr, "%d - %s: destination sending reply\n",00749 index, __FUNCTION__);

00750 #endif // DEBUG

00751

00752

00753 // Just to be safe, I use the max. Somebody may have

00754 // incremented the dst seqno.

00755 seqno = max(seqno, rq->rq_dst_seqno)+1;

00756 if (seqno%2) seqno++;

00757

00758 sendReply(rq->rq_src, // IP Destination00759 1, // Hop Count

00760 index, // Dest IP Address

00761 seqno, // Dest Sequence Num

00762 MY_ROUTE_TIMEOUT, // Lifetime

00763 rq->rq_timestamp); // timestamp

00764

00765 Packet::free(p);

00766 }

00767

00768 // I am not the destination, but I may have a fresh enough route.

00769

00770 else if (rt && (rt->rt_hops != INFINITY2) &&

00771 (rt->rt_seqno >= rq->rq_dst_seqno) ) {

00772

00773 //assert (rt->rt_flags == RTF_UP);

00774 assert(rq->rq_dst == rt->rt_dst);

00775 //assert ((rt->rt_seqno%2) == 0); // is the seqno even?

00776 sendReply(rq->rq_src,

00777 rt->rt_hops + 1,

00778 rq->rq_dst,

00779 rt->rt_seqno,00780 (u_int32_t) (rt->rt_expire - CURRENT_TIME),

Page 18: Aodv Patch

5/14/2018 Aodv Patch - slidepdf.com

http://slidepdf.com/reader/full/aodv-patch 18/31

 

00781 // rt->rt_expire - CURRENT_TIME,

00782 rq->rq_timestamp);

00783 // Insert nexthops to RREQ source and RREQ destination in the

00784 // precursor lists of destination and source respectively

00785 rt->pc_insert(rt0->rt_nexthop); // nexthop to RREQ source

00786 rt0->pc_insert(rt->rt_nexthop); // nexthop to RREQ destination

00787

00788 #ifdef RREQ_GRAT_RREP

00789

00790 sendReply(rq->rq_dst,

00791 rq->rq_hop_count,

00792 rq->rq_src,

00793 rq->rq_src_seqno,

00794 (u_int32_t) (rt->rt_expire - CURRENT_TIME),

00795 // rt->rt_expire - CURRENT_TIME,

00796 rq->rq_timestamp);00797 #endif

00798

00799 // TODO: send grat RREP to dst if G flag set in RREQ using rq->rq_src_seqno, rq->rq_hop_counT

00800

00801 // DONE: Included gratuitous replies to be sent as per IETF aodvdraft specification. As of now, G flag has not been dynamically used andis always set or reset in aodv-packet.h --- Anant Utgikar, 09/16/02.

00802

00803 Packet::free(p);

00804 }00805 /*

00806 * Can't reply. So forward the Route Request

00807 */

00808 else {

00809 ih->saddr() = index;

00810 ih->daddr() = IP_BROADCAST;

00811 rq->rq_hop_count += 1;

00812 // Maximum sequence number seen en route

00813 if (rt) rq->rq_dst_seqno = max(rt->rt_seqno, rq->rq_dst_seqno);

00814 forward((aodv_rt_entry*) 0, p, DELAY);00815 }

00816

00817 }

00818

00819

00820 void

00821 AODV::recvReply(Packet *p) {

00822 //struct hdr_cmn *ch = HDR_CMN(p);

00823 struct hdr_ip *ih = HDR_IP(p);

00824 struct hdr_aodv_reply *rp = HDR_AODV_REPLY(p);

00825 aodv_rt_entry *rt;

Page 19: Aodv Patch

5/14/2018 Aodv Patch - slidepdf.com

http://slidepdf.com/reader/full/aodv-patch 19/31

 

00826 char suppress_reply = 0;

00827 double delay = 0.0;

00828

00829 #ifdef DEBUG

00830 fprintf(stderr, "%d - %s: received a REPLY\n", index,

__FUNCTION__);

00831 #endif // DEBUG

00832

00833

00834 /*

00835 * Got a reply. So reset the "soft state" maintained for

00836 * route requests in the request table. We don't really have

00837 * have a separate request table. It is just a part of the

00838 * routing table itself.

00839 */

00840 // Note that rp_dst is the dest of the data packets, not the00841 // the dest of the reply, which is the src of the data packets.

00842

00843 rt = rtable.rt_lookup(rp->rp_dst);

00844

00845 /*

00846 * If I don't have a rt entry to this host... adding

00847 */

00848 if(rt == 0) {

00849 rt = rtable.rt_add(rp->rp_dst);

00850 }

00851

00852 /*

00853 * Add a forward route table entry... here I am following

00854 * Perkins-Royer AODV paper almost literally - SRD 5/99

00855 */

00856

00857 if ( (rt->rt_seqno < rp->rp_dst_seqno) || // newer route

00858 ((rt->rt_seqno == rp->rp_dst_seqno) &&

00859 (rt->rt_hops > rp->rp_hop_count)) ) { // shorter or betterroute

0086000861 // Update the rt entry

00862 rt_update(rt, rp->rp_dst_seqno, rp->rp_hop_count,

00863 rp->rp_src, CURRENT_TIME + rp->rp_lifetime);

00864

00865 // reset the soft state

00866 rt->rt_req_cnt = 0;

00867 rt->rt_req_timeout = 0.0;

00868 rt->rt_req_last_ttl = rp->rp_hop_count;

00869

00870 if (ih->daddr() == index) { // If I am the original source00871 // Update the route discovery latency statistics

Page 20: Aodv Patch

5/14/2018 Aodv Patch - slidepdf.com

http://slidepdf.com/reader/full/aodv-patch 20/31

 

00872 // rp->rp_timestamp is the time of request origination

00873

00874 rt->rt_disc_latency[(unsigned char)rt->hist_indx] =(CURRENT_TIME - rp->rp_timestamp)

00875 / (double) rp-

>rp_hop_count;00876 // increment indx for next time

00877 rt->hist_indx = (rt->hist_indx + 1) % MAX_HISTORY;

00878 }

00879

00880 /*

00881 * Send all packets queued in the sendbuffer destined for

00882 * this destination.

00883 * XXX - observe the "second" use of p.

00884 */

00885 Packet *buf_pkt;

00886 while((buf_pkt = rqueue.deque(rt->rt_dst))) {

00887 if(rt->rt_hops != INFINITY2) {

00888 assert (rt->rt_flags == RTF_UP);

00889 // Delay them a little to help ARP. Otherwise ARP

00890 // may drop packets. -SRD 5/23/99

00891 forward(rt, buf_pkt, delay);

00892 delay += ARP_DELAY;

00893 }

00894 }

00895 }

00896 else {

00897 suppress_reply = 1;

00898 }

00899

00900 /*

00901 * If reply is for me, discard it.

00902 */

00903

00904 if(ih->daddr() == index || suppress_reply) {

00905 Packet::free(p);

00906 }00907 /*

00908 * Otherwise, forward the Route Reply.

00909 */

00910 else {

00911 // Find the rt entry

00912 aodv_rt_entry *rt0 = rtable.rt_lookup(ih->daddr());

00913 // If the rt is up, forward

00914 if(rt0 && (rt0->rt_hops != INFINITY2)) {

00915 assert (rt0->rt_flags == RTF_UP);

00916 rp->rp_hop_count += 1;00917 rp->rp_src = index;

Page 21: Aodv Patch

5/14/2018 Aodv Patch - slidepdf.com

http://slidepdf.com/reader/full/aodv-patch 21/31

 

00918 forward(rt0, p, NO_DELAY);

00919 // Insert the nexthop towards the RREQ source to

00920 // the precursor list of the RREQ destination

00921 rt->pc_insert(rt0->rt_nexthop); // nexthop to RREQ source

00922

00923 }

00924 else {

00925 // I don't know how to forward .. drop the reply.

00926 #ifdef DEBUG

00927 fprintf(stderr, "%s: dropping Route Reply\n", __FUNCTION__);

00928 #endif // DEBUG

00929 drop(p, DROP_RTR_NO_ROUTE);

00930 }

00931 }

00932 }

0093300934

00935 void

00936 AODV::recvError(Packet *p) {

00937 struct hdr_ip *ih = HDR_IP(p);

00938 struct hdr_aodv_error *re = HDR_AODV_ERROR(p);

00939 aodv_rt_entry *rt;

00940 u_int8_t i;

00941 Packet *rerr = Packet::alloc();

00942 struct hdr_aodv_error *nre = HDR_AODV_ERROR(rerr);

0094300944 nre->DestCount = 0;

00945

00946 for (i=0; i<re->DestCount; i++) {

00947 // For each unreachable destination

00948 rt = rtable.rt_lookup(re->unreachable_dst[i]);

00949 if ( rt && (rt->rt_hops != INFINITY2) &&

00950 (rt->rt_nexthop == ih->saddr()) &&

00951 (rt->rt_seqno <= re->unreachable_dst_seqno[i]) ) {

00952 assert(rt->rt_flags == RTF_UP);

00953 assert((rt->rt_seqno%2) == 0); // is the seqno even?

00954 #ifdef DEBUG

00955 fprintf(stderr, "%s(%f): %d\t(%d\t%u\t%d)\t(%d\t%u\t%d)\n",__FUNCTION__,CURRENT_TIME,

00956 index, rt->rt_dst, rt->rt_seqno, rt->rt_nexthop,

00957 re->unreachable_dst[i],re->unreachable_dst_seqno[i],

00958 ih->saddr());

00959 #endif // DEBUG

00960 rt->rt_seqno = re->unreachable_dst_seqno[i];

00961 rt_down(rt);

00962

00963 // Not sure whether this is the right thing to do00964 Packet *pkt;

Page 22: Aodv Patch

5/14/2018 Aodv Patch - slidepdf.com

http://slidepdf.com/reader/full/aodv-patch 22/31

 

00965 while((pkt = ifqueue->filter(ih->saddr()))) {

00966 drop(pkt, DROP_RTR_MAC_CALLBACK);

00967 }

00968

00969 // if precursor list non-empty add to RERR and delete the

precursor list

00970 if (!rt->pc_empty()) {

00971 nre->unreachable_dst[nre->DestCount] = rt->rt_dst;

00972 nre->unreachable_dst_seqno[nre->DestCount] = rt->rt_seqno;

00973 nre->DestCount += 1;

00974 rt->pc_delete();

00975 }

00976 }

00977 }

00978

00979 if (nre->DestCount > 0) {

00980 #ifdef DEBUG

00981 fprintf(stderr, "%s(%f): %d\t sending RERR...\n", __FUNCTION__,CURRENT_TIME, index);

00982 #endif // DEBUG

00983 sendError(rerr);

00984 }

00985 else {

00986 Packet::free(rerr);

00987 }

0098800989 Packet::free(p);

00990 }

00991

00992

00993 /*

00994 Packet Transmission Routines

00995 */

00996

00997 void

00998 AODV::forward(aodv_rt_entry *rt, Packet *p, double delay) {00999 struct hdr_cmn *ch = HDR_CMN(p);

01000 struct hdr_ip *ih = HDR_IP(p);

01001

01002 if(ih->ttl_ == 0) {

01003

01004 #ifdef DEBUG

01005 fprintf(stderr, "%s: calling drop()\n", __PRETTY_FUNCTION__);

01006 #endif // DEBUG

01007

01008 drop(p, DROP_RTR_TTL);

01009 return;

Page 23: Aodv Patch

5/14/2018 Aodv Patch - slidepdf.com

http://slidepdf.com/reader/full/aodv-patch 23/31

 

01010 }

01011

01012 if (ch->ptype() != PT_AODV && ch->direction() == hdr_cmn::UP &&

01013 ((u_int32_t)ih->daddr() == IP_BROADCAST)

01014 || (ih->daddr() == here_.addr_)) {

01015 dmux_->recv(p,0);

01016 return;

01017 }

01018

01019 if (rt) {

01020 assert(rt->rt_flags == RTF_UP);

01021 rt->rt_expire = CURRENT_TIME + ACTIVE_ROUTE_TIMEOUT;

01022 ch->next_hop_ = rt->rt_nexthop;

01023 ch->addr_type() = NS_AF_INET;

01024 ch->direction() = hdr_cmn::DOWN; //important: change the

packet's direction01025 }

01026 else { // if it is a broadcast packet

01027 // assert(ch->ptype() == PT_AODV); // maybe a diff pkt typelike gaf

01028 assert(ih->daddr() == (nsaddr_t) IP_BROADCAST);

01029 ch->addr_type() = NS_AF_NONE;

01030 ch->direction() = hdr_cmn::DOWN; //important: change thepacket's direction

01031 }

01032

01033 if (ih->daddr() == (nsaddr_t) IP_BROADCAST) {01034 // If it is a broadcast packet

01035 assert(rt == 0);

01036 /*

01037 * Jitter the sending of broadcast packets by 10ms

01038 */

01039 Scheduler::instance().schedule(target_, p,

01040 0.01 * Random::uniform());

01041 }

01042 else { // Not a broadcast packet

01043 if(delay > 0.0) {01044 Scheduler::instance().schedule(target_, p, delay);

01045 }

01046 else {

01047 // Not a broadcast packet, no delay, send immediately

01048 Scheduler::instance().schedule(target_, p, 0.);

01049 }

01050 }

01051

01052 }

01053

01054

Page 24: Aodv Patch

5/14/2018 Aodv Patch - slidepdf.com

http://slidepdf.com/reader/full/aodv-patch 24/31

 

01055 void

01056 AODV::sendRequest(nsaddr_t dst) {

01057 // Allocate a RREQ packet

01058 Packet *p = Packet::alloc();

01059 struct hdr_cmn *ch = HDR_CMN(p);

01060 struct hdr_ip *ih = HDR_IP(p);

01061 struct hdr_aodv_request *rq = HDR_AODV_REQUEST(p);

01062 aodv_rt_entry *rt = rtable.rt_lookup(dst);

01063

01064 assert(rt);

01065

01066 /*

01067 * Rate limit sending of Route Requests. We are veryconservative

01068 * about sending out route requests.

01069 */01070

01071 if (rt->rt_flags == RTF_UP) {

01072 assert(rt->rt_hops != INFINITY2);

01073 Packet::free((Packet *)p);

01074 return;

01075 }

01076

01077 if (rt->rt_req_timeout > CURRENT_TIME) {

01078 Packet::free((Packet *)p);

01079 return;

01080 }

01081

01082 // rt_req_cnt is the no. of times we did network-wide broadcast

01083 // RREQ_RETRIES is the maximum number we will allow before

01084 // going to a long timeout.

01085

01086 if (rt->rt_req_cnt > RREQ_RETRIES) {

01087 rt->rt_req_timeout = CURRENT_TIME + MAX_RREQ_TIMEOUT;

01088 rt->rt_req_cnt = 0;

01089 Packet *buf_pkt;

01090 while ((buf_pkt = rqueue.deque(rt->rt_dst))) {

01091 drop(buf_pkt, DROP_RTR_NO_ROUTE);

01092 }

01093 Packet::free((Packet *)p);

01094 return;

01095 }

01096

01097 #ifdef DEBUG

01098 fprintf(stderr, "(%2d) - %2d sending Route Request, dst: %d\n",

01099 ++route_request, index, rt->rt_dst);

01100 #endif // DEBUG01101

Page 25: Aodv Patch

5/14/2018 Aodv Patch - slidepdf.com

http://slidepdf.com/reader/full/aodv-patch 25/31

 

01102 // Determine the TTL to be used this time.

01103 // Dynamic TTL evaluation - SRD

01104

01105 rt->rt_req_last_ttl = max(rt->rt_req_last_ttl,rt->rt_last_hop_count);

01106

01107 if (0 == rt->rt_req_last_ttl) {

01108 // first time query broadcast

01109 ih->ttl_ = TTL_START;

01110 }

01111 else {

01112 // Expanding ring search.

01113 if (rt->rt_req_last_ttl < TTL_THRESHOLD)

01114 ih->ttl_ = rt->rt_req_last_ttl + TTL_INCREMENT;

01115 else {

01116 // network-wide broadcast01117 ih->ttl_ = NETWORK_DIAMETER;

01118 rt->rt_req_cnt += 1;

01119 }

01120 }

01121

01122 // remember the TTL used for the next time

01123 rt->rt_req_last_ttl = ih->ttl_;

01124

01125 // PerHopTime is the roundtrip time per hop for route requests.

01126 // The factor 2.0 is just to be safe .. SRD 5/22/99

01127 // Also note that we are making timeouts to be larger if we have

01128 // done network wide broadcast before.

01129

01130 rt->rt_req_timeout = 2.0 * (double) ih->ttl_ * PerHopTime(rt);

01131 if (rt->rt_req_cnt > 0)

01132 rt->rt_req_timeout *= rt->rt_req_cnt;

01133 rt->rt_req_timeout += CURRENT_TIME;

01134

01135 // Don't let the timeout to be too large, however .. SRD 6/8/99

01136 if (rt->rt_req_timeout > CURRENT_TIME + MAX_RREQ_TIMEOUT)

01137 rt->rt_req_timeout = CURRENT_TIME + MAX_RREQ_TIMEOUT;

01138 rt->rt_expire = 0;

01139

01140 #ifdef DEBUG

01141 fprintf(stderr, "(%2d) - %2d sending Route Request, dst: %d, tout%f ms\n",

01142 ++route_request,

01143 index, rt->rt_dst,

01144 rt->rt_req_timeout - CURRENT_TIME);

01145 #endif // DEBUG

0114601147

Page 26: Aodv Patch

5/14/2018 Aodv Patch - slidepdf.com

http://slidepdf.com/reader/full/aodv-patch 26/31

 

01148 // Fill out the RREQ packet

01149 // ch->uid() = 0;

01150 ch->ptype() = PT_AODV;

01151 ch->size() = IP_HDR_LEN + rq->size();

01152 ch->iface() = -2;

01153 ch->error() = 0;

01154 ch->addr_type() = NS_AF_NONE;

01155 ch->prev_hop_ = index; // AODV hack

01156

01157 ih->saddr() = index;

01158 ih->daddr() = IP_BROADCAST;

01159 ih->sport() = RT_PORT;

01160 ih->dport() = RT_PORT;

01161

01162 // Fill up some more fields.

01163 rq->rq_type = AODVTYPE_RREQ;01164 rq->rq_hop_count = 1;

01165 rq->rq_bcast_id = bid++;

01166 rq->rq_dst = dst;

01167 rq->rq_dst_seqno = (rt ? rt->rt_seqno : 0);

01168 rq->rq_src = index;

01169 seqno += 2;

01170 assert ((seqno%2) == 0);

01171 rq->rq_src_seqno = seqno;

01172 rq->rq_timestamp = CURRENT_TIME;

0117301174 Scheduler::instance().schedule(target_, p, 0.);

01175

01176 }

01177

01178 void

01179 AODV::sendReply(nsaddr_t ipdst, u_int32_t hop_count, nsaddr_t rpdst,

01180 u_int32_t rpseq, u_int32_t lifetime, doubletimestamp) {

01181 Packet *p = Packet::alloc();

01182 struct hdr_cmn *ch = HDR_CMN(p);01183 struct hdr_ip *ih = HDR_IP(p);

01184 struct hdr_aodv_reply *rp = HDR_AODV_REPLY(p);

01185 aodv_rt_entry *rt = rtable.rt_lookup(ipdst);

01186

01187 #ifdef DEBUG

01188 fprintf(stderr, "sending Reply from %d at %.2f\n", index,Scheduler::instance().clock());

01189 #endif // DEBUG

01190 assert(rt);

01191

01192 rp->rp_type = AODVTYPE_RREP;

Page 27: Aodv Patch

5/14/2018 Aodv Patch - slidepdf.com

http://slidepdf.com/reader/full/aodv-patch 27/31

 

01193 //rp->rp_flags = 0x00;

01194 rp->rp_hop_count = hop_count;

01195 rp->rp_dst = rpdst;

01196 rp->rp_dst_seqno = rpseq;

01197 rp->rp_src = index;

01198 rp->rp_lifetime = lifetime;

01199 rp->rp_timestamp = timestamp;

01200

01201 // ch->uid() = 0;

01202 ch->ptype() = PT_AODV;

01203 ch->size() = IP_HDR_LEN + rp->size();

01204 ch->iface() = -2;

01205 ch->error() = 0;

01206 ch->addr_type() = NS_AF_INET;

01207 ch->next_hop_ = rt->rt_nexthop;

01208 ch->prev_hop_ = index; // AODV hack01209 ch->direction() = hdr_cmn::DOWN;

01210

01211 ih->saddr() = index;

01212 ih->daddr() = ipdst;

01213 ih->sport() = RT_PORT;

01214 ih->dport() = RT_PORT;

01215 ih->ttl_ = NETWORK_DIAMETER;

01216

01217 Scheduler::instance().schedule(target_, p, 0.);

0121801219 }

01220

01221 void

01222 AODV::sendError(Packet *p, bool jitter) {

01223 struct hdr_cmn *ch = HDR_CMN(p);

01224 struct hdr_ip *ih = HDR_IP(p);

01225 struct hdr_aodv_error *re = HDR_AODV_ERROR(p);

01226

01227 #ifdef ERROR

01228 fprintf(stderr, "sending Error from %d at %.2f\n", index,

Scheduler::instance().clock());

01229 #endif // DEBUG

01230

01231 re->re_type = AODVTYPE_RERR;

01232 //re->reserved[0] = 0x00; re->reserved[1] = 0x00;

01233 // DestCount and list of unreachable destinations are alreadyfilled

01234

01235 // ch->uid() = 0;

01236 ch->ptype() = PT_AODV;

01237 ch->size() = IP_HDR_LEN + re->size();01238 ch->iface() = -2;

Page 28: Aodv Patch

5/14/2018 Aodv Patch - slidepdf.com

http://slidepdf.com/reader/full/aodv-patch 28/31

 

01239 ch->error() = 0;

01240 ch->addr_type() = NS_AF_NONE;

01241 ch->next_hop_ = 0;

01242 ch->prev_hop_ = index; // AODV hack

01243 ch->direction() = hdr_cmn::DOWN; //important: change the

packet's direction

01244

01245 ih->saddr() = index;

01246 ih->daddr() = IP_BROADCAST;

01247 ih->sport() = RT_PORT;

01248 ih->dport() = RT_PORT;

01249 ih->ttl_ = 1;

01250

01251 // Do we need any jitter? Yes

01252 if (jitter)

01253 Scheduler::instance().schedule(target_, p,0.01*Random::uniform());

01254 else

01255 Scheduler::instance().schedule(target_, p, 0.0);

01256

01257 }

01258

01259

01260 /*

01261 Neighbor Management Functions

01262 */

01263

01264 void

01265 AODV::sendHello() {

01266 Packet *p = Packet::alloc();

01267 struct hdr_cmn *ch = HDR_CMN(p);

01268 struct hdr_ip *ih = HDR_IP(p);

01269 struct hdr_aodv_reply *rh = HDR_AODV_REPLY(p);

01270

01271 #ifdef DEBUG

01272 fprintf(stderr, "sending Hello from %d at %.2f\n", index,

Scheduler::instance().clock());01273 #endif // DEBUG

01274

01275 rh->rp_type = AODVTYPE_HELLO;

01276 //rh->rp_flags = 0x00;

01277 rh->rp_hop_count = 1;

01278 rh->rp_dst = index;

01279 rh->rp_dst_seqno = seqno;

01280 rh->rp_lifetime = (1 + ALLOWED_HELLO_LOSS) * HELLO_INTERVAL;

01281

01282 // ch->uid() = 0;

01283 ch->ptype() = PT_AODV;

Page 29: Aodv Patch

5/14/2018 Aodv Patch - slidepdf.com

http://slidepdf.com/reader/full/aodv-patch 29/31

 

01284 ch->size() = IP_HDR_LEN + rh->size();

01285 ch->iface() = -2;

01286 ch->error() = 0;

01287 ch->addr_type() = NS_AF_NONE;

01288 ch->prev_hop_ = index; // AODV hack

01289

01290 ih->saddr() = index;

01291 ih->daddr() = IP_BROADCAST;

01292 ih->sport() = RT_PORT;

01293 ih->dport() = RT_PORT;

01294 ih->ttl_ = 1;

01295

01296 Scheduler::instance().schedule(target_, p, 0.0);

01297 }

01298

0129901300 void

01301 AODV::recvHello(Packet *p) {

01302 //struct hdr_ip *ih = HDR_IP(p);

01303 struct hdr_aodv_reply *rp = HDR_AODV_REPLY(p);

01304 AODV_Neighbor *nb;

01305

01306 nb = nb_lookup(rp->rp_dst);

01307 if(nb == 0) {

01308 nb_insert(rp->rp_dst);

01309 }01310 else {

01311 nb->nb_expire = CURRENT_TIME +

01312 (1.5 * ALLOWED_HELLO_LOSS * HELLO_INTERVAL);

01313 }

01314

01315 Packet::free(p);

01316 }

01317

01318 void

01319 AODV::nb_insert(nsaddr_t id) {

01320 AODV_Neighbor *nb = new AODV_Neighbor(id);

01321

01322 assert(nb);

01323 nb->nb_expire = CURRENT_TIME +

01324 (1.5 * ALLOWED_HELLO_LOSS * HELLO_INTERVAL);

01325 LIST_INSERT_HEAD(&nbhead, nb, nb_link);

01326 seqno += 2; // set of neighbors changed

01327 assert ((seqno%2) == 0);

01328 }

01329

0133001331 AODV_Neighbor*

Page 30: Aodv Patch

5/14/2018 Aodv Patch - slidepdf.com

http://slidepdf.com/reader/full/aodv-patch 30/31

 

01332 AODV::nb_lookup(nsaddr_t id) {

01333 AODV_Neighbor *nb = nbhead.lh_first;

01334

01335 for(; nb; nb = nb->nb_link.le_next) {

01336 if(nb->nb_addr == id) break;

01337 }

01338 return nb;

01339 }

01340

01341

01342 /*

01343 * Called when we receive *explicit* notification that a Neighbor

01344 * is no longer reachable.

01345 */

01346 void

01347 AODV::nb_delete(nsaddr_t id) {01348 AODV_Neighbor *nb = nbhead.lh_first;

01349

01350 log_link_del(id);

01351 seqno += 2; // Set of neighbors changed

01352 assert ((seqno%2) == 0);

01353

01354 for(; nb; nb = nb->nb_link.le_next) {

01355 if(nb->nb_addr == id) {

01356 LIST_REMOVE(nb,nb_link);

01357 delete nb;01358 break;

01359 }

01360 }

01361

01362 handle_link_failure(id);

01363

01364 }

01365

01366

01367 /*

01368 * Purges all timed-out Neighbor Entries - runs every

01369 * HELLO_INTERVAL * 1.5 seconds.

01370 */

01371 void

01372 AODV::nb_purge() {

01373 AODV_Neighbor *nb = nbhead.lh_first;

01374 AODV_Neighbor *nbn;

01375 double now = CURRENT_TIME;

01376

01377 for(; nb; nb = nbn) {

01378 nbn = nb->nb_link.le_next;01379 if(nb->nb_expire <= now) {