Aodv Patch
Transcript of 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
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
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) {
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());
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 /*
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;
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);
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);
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
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) {
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
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.
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;
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);
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 /*
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 }
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),
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;
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
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;
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;
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;
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
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
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
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;
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;
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;
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*
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) {
5/14/2018 Aodv Patch - slidepdf.com
http://slidepdf.com/reader/full/aodv-patch 31/31
01380 nb_delete(nb->nb_addr);
01381 }
01382 }
01383
01384 }