diff -u -b -N ns-2.1b6/Makefile.in proactive-ns-2.1b6/Makefile.in
--- ns-2.1b6/Makefile.in	Thu Jan  6 14:08:23 2000
+++ proactive-ns-2.1b6/Makefile.in	Thu Oct  2 20:46:09 2003
@@ -150,7 +150,7 @@
 	tora/tora.o tora/tora_api.o tora/tora_dest.o tora/tora_io.o \
 	tora/tora_logs.o tora/tora_neighbor.o \
 	dsr/dsragent.o dsr/hdr_sr.o dsr/mobicache.o dsr/path.o \
-	dsr/requesttable.o dsr/routecache.o \
+	dsr/requesttable.o dsr/routecache.o dsr/proactive.o \
 	aodv/aodv_logs.o aodv/aodv.o \
 	ns-process.o \
 	satgeometry.o sathandoff.o satlink.o satnode.o \
diff -u -b -N ns-2.1b6/aodv/aodv.cc proactive-ns-2.1b6/aodv/aodv.cc
--- ns-2.1b6/aodv/aodv.cc	Mon Nov 29 23:25:32 1999
+++ proactive-ns-2.1b6/aodv/aodv.cc	Fri Oct  3 00:12:19 2003
@@ -167,6 +165,10 @@
         rqueue()
 {
         bind("off_AODV_", &off_AODV_);
+#ifdef PRO_AODV
+	bind("PAThresh_",&PAThresh_);
+	bind("proactive_",&proactive);
+#endif
                 
         index = id;
         seqno = 1;
@@ -558,6 +560,10 @@
      */
 	
         if(rt->rt_flags == RTF_UP) {
+	  // fprintf(stderr,"packet from %d to next hop %d\n",index,rt->rt_nexthop);
+/*if I am originator and the route is warned set the threshold value to 0 */
+	  if(ih->saddr() == index && ch->num_forwards() == 0 && rt->rt_warn)
+	    ch->warning_thresh()=0.0;
                 forward(rt, p, NO_DELAY);
         }
 	/*
@@ -573,6 +579,9 @@
 	//        else if(ih->src_ == index) {
 	else if(ih->saddr() == index) {
                 rqueue.enque(p);
+#ifdef DEBUG
+		fprintf(stderr,"%s:a route request sent to %d\n",__FUNCTION__,rt->rt_dst);
+#endif
                 sendRequest(rt->rt_dst);
         }
         /*
@@ -620,6 +629,7 @@
 				drop(p, DROP_RTR_NO_ROUTE);
                         }
 			rt->rt_flags = RTF_DOWN;
+	                //fprintf(stderr,"route to %d at %d down\n",rt->rt_dst,index);
 
 			/*  LIST_REMOVE(rt, rt_link);
                         delete rt; 
@@ -650,6 +660,94 @@
         }
 }
 
+#ifdef PRO_AODV
+/* =====================================================================
+   Proactivity Routines
+   ===================================================================== */
+int
+AODV::need_proactive_route_maintenance(Packet *p)
+{
+  hdr_ip *iph = (hdr_ip*)p->access(off_ip_);
+  hdr_cmn *cmh = (hdr_cmn*)p->access(off_cmn_);
+
+  /*
+  fprintf(stderr,"rado:%e the signal power\n",p->txinfo_.RxPr);
+  fprintf(stderr,"rado:%e the threshhol power\n",cmh->warning_thresh());
+  */
+
+  assert(cmh->size()>=0);
+  assert(proactive);
+  /*
+  if(cmh->hacked){
+    fprintf(stderr,"Proactivity check for hacked packet\n");
+    fprintf(stderr,"rado:%e the signal power\n",p->txinfo_.RxPr);
+    fprintf(stderr,"rado:%e the threshhol power\n",cmh->warning_thresh());
+    fprintf(stderr,"My ip is %d, dest of this packet is %d\n",index,iph->daddr());
+    }*/
+
+ return (p->txinfo_.RxPr <= cmh->warning_thresh()) ? 1 : 0;
+}
+
+void
+AODV::do_proactive_route_maintenance(Packet *p)
+{
+  hdr_ip *iph = (hdr_ip*)p->access(off_ip_);
+  hdr_cmn *cmh = (hdr_cmn*)p->access(off_cmn_);
+
+  //lower warning threshold in the original packet (avoid duplicate warns)
+  cmh->warning_thresh()=0.0;
+
+  sendWarn(iph->saddr(),         // IP Destination
+	   0,                    // Hop Count
+	   index,                // Warner IP Address
+	   seqno,                // Warner Sequence Num
+	   MY_ROUTE_TIMEOUT,     // Lifetime
+	   iph->daddr());        //the ultimate dest address of the route
+}
+
+void
+AODV::recvWarn(Packet *p)
+{
+  struct hdr_ip *ih =(hdr_ip*)p->access(off_ip_) ;
+  struct hdr_aodv_warn *wr = (hdr_aodv_warn*)p->access(off_AODV_);
+  struct hdr_cmn *ch = (hdr_cmn*)p->access(off_cmn_) ;
+
+  rt_entry *rt;
+
+  rt = rtable.rt_lookup(wr->rw_warn_dest);
+
+  if(rt){
+    if(wr->rw_dst==index){
+      if(!(rt->rt_warn)){
+	rt->rt_warn=1;
+	sendRequest(rt->rt_dst);
+	//fprintf(stderr,"%d warning came and new Req has been sent\n",index);
+      }
+      Packet::free(p);
+    }
+    else {
+      /* set the route warned, and forward the warning */
+
+      rt_entry *rt0 = rtable.rt_lookup(wr->rw_dst);
+      if(rt0)
+
+      if(rt0 && (rt0->rt_flags == RTF_UP)) {
+	wr->rw_hop_count +=1;
+	forward(rt0,p,NO_DELAY);
+      }
+      else {
+	fprintf(stderr,"%d:Dont know back route for the warning to %d\n",index,wr->rw_dst);
+	Packet::free(p);
+      }
+    }
+  }
+  else {
+    fprintf(stderr,"I dont know this dest to warn the source of it\n");
+    Packet::free(p);
+  }
+  return;
+}
+#endif
 
 /* =====================================================================
    Packet Reception Routines
@@ -663,6 +761,28 @@
         assert(initialized());
         //assert(p->incoming == 0);
 
+	if((ch->ptype() == PT_AODV)&&(ch->hacked())) {
+	 if (proactive && (ih->daddr() == index))
+	    {
+	       // to keep alive the back route
+
+	   rt_entry *rt0;
+	   if( rt0 = rtable.rt_lookup(ih->saddr())){
+	     // fprintf(stderr,"% is keeping alive route to %d\n",index,ih->saddr());
+	     rt0->rt_flags=RTF_UP;
+	    rt0->rt_expire = CURRENT_TIME + ACTIVE_ROUTE_TIMEOUT;
+	   }
+
+	  if (need_proactive_route_maintenance(p))
+	  {
+	    //fprintf(stderr,"%d Hacked, proactive, dest, and needs maintenace\n",index);
+	    do_proactive_route_maintenance(p);
+	   }
+	    }
+	   Packet::free(p);
+	   return;
+	}
+
         if(ch->ptype() == PT_AODV) {
 
                 ih->ttl_ -= 1;
@@ -682,6 +803,8 @@
                 ch->size() += IP_HDR_LEN;
 
                 ih->ttl_ = NETWORK_DIAMETER;
+
+		ch->warning_thresh()=PAThresh();
         }
         /*
          *  I received a packet that I sent.  Probably
@@ -703,8 +826,23 @@
                         drop(p, DROP_RTR_TTL);
                         return;
                 }
+		//fprintf(stderr, "rado: %d is forwarding a packet\n",index);
+
+	   // to keep alive the back route
+
+	   rt_entry *rt0;
+	   if( rt0 = rtable.rt_lookup(ih->saddr())){
+	     // fprintf(stderr,"% is keeping alive route to %d\n",index,ih->saddr());
+	     rt0->rt_flags=RTF_UP;
+	    rt0->rt_expire = CURRENT_TIME + ACTIVE_ROUTE_TIMEOUT;
         }
 
+	   if (proactive && ((ih->daddr()) != IP_BROADCAST) &&
+	   	  need_proactive_route_maintenance(p))
+	         {
+			do_proactive_route_maintenance(p);
+			      }
+        }
         rt_resolve(p);
 }
 
@@ -740,6 +878,9 @@
         case AODVTYPE_UREP:
              recvTriggeredReply(p);
              break;
+	 case AODVTYPE_WARN:
+	   recvWarn(p);
+	   break;
         default:
              fprintf(stderr, "Invalid AODV type (%x)\n", ah->ah_type);
              exit(1);
@@ -756,12 +897,23 @@
 
         /*
          * Drop if:
+	 *      - The received request is below thresh and the simulation
+	 is proactive
          *      - I'm the source
          *      - I recently heard this request.
          */
+
+	//not to process a request under the treshhold value
+	//fprintf(stderr,"%d checks for threshold of the request\n",index);
+       	if(proactive && need_proactive_route_maintenance(p)){
+	  // fprintf(stderr,"%d received a request for dest %d with b_id %d below thresh\n",index,rq->rq_dst,rq->rq_bcast_id);
+	           Packet::free(p);
+                return;
+		}
+
         if(rq->rq_src == index) {
 #ifdef DEBUG
-       fprintf(stderr, "%s: got my own REQUEST\n", __FUNCTION__);
+       fprintf(stderr, "%s: %d got my own REQUEST from %d with b_id %d\n", __FUNCTION__,index,ih->saddr(),rq->rq_bcast_id);
 #endif
                 Packet::free(p);
                 return;
@@ -770,7 +922,7 @@
 	if (id_lookup(rq->rq_src,rq->rq_bcast_id) == ID_FOUND) {
 
 #ifdef DEBUG
-    fprintf(stderr, "%s: discarding request\n", __FUNCTION__);
+    fprintf(stderr, "%s: %d discarding request from %d with b_id %d\n", __FUNCTION__,index,ih->saddr(),rq->rq_bcast_id);
 #endif
            Packet::free(p);
            return;
@@ -872,8 +1027,8 @@
 
         if(rq->rq_dst == index) {
 #ifdef DEBUG
-             fprintf(stderr, "%d - %s: destination sending reply\n",
-                     index, __FUNCTION__);
+             fprintf(stderr, "%d - %s: destination sending reply to req with b_id %d received from %d\n",
+                     index, __FUNCTION__,rq->rq_bcast_id,ih->saddr());
 #endif
                
              // Just to be safe, I use the max. Somebody may have
@@ -881,7 +1036,7 @@
 	     //
              seqno = max((unsigned)seqno, (unsigned)rq->rq_dst_seqno) + 1;
              sendReply(rq->rq_src,           // IP Destination
-                       0,                    // Hop Count
+                       1,                    // Hop Count
                        index,                // Dest IP Address
                        seqno,                // Dest Sequence Num
                        MY_ROUTE_TIMEOUT,     // Lifetime
@@ -929,13 +1084,14 @@
 	double delay = 0.0;
 
 #ifdef DEBUG
-        fprintf(stderr, "%d - %s: received a REPLY\n", index, __FUNCTION__);
+        fprintf(stderr, "%d - %s: received a REPLY from %d for dest %d\n", index, __FUNCTION__,ch->prev_hop_,rp->rp_dst);
 #endif
        
         /*
          *  Handle "Route Errors" separately...
          */
         if(rp->rp_hop_count == INFINITY2) {
+	  fprintf(stderr,"%d triggerered reply came\n",index);
                 recvTriggeredReply(p);
                 return;
         }
@@ -953,6 +1109,7 @@
 
         if((rt = rtable.rt_lookup(rp->rp_dst))) {
 		// reset the soft state
+	  rt->rt_warn=0;
 	        rt->rt_req_cnt = 0;
             rt->rt_req_timeout = 0.0; 
             if (rp->rp_hop_count != INFINITY2)
@@ -976,6 +1133,7 @@
              ((rt->rt_seqno == rp->rp_dst_seqno) &&  
 		   	  (rt->rt_hops > rp->rp_hop_count)))) { // shorter or equal route
 	 
+	  //fprintf(stderr,"route is being updated\n");
 	  // Update the rt entry 
              rt->rt_expire = CURRENT_TIME + rp->rp_lifetime;
 #ifdef ERROR_BROADCAST
@@ -1013,6 +1171,7 @@
 
         //if(ih->dst_ == index) {
 	if(ih->daddr() == index) {
+	  // fprintf(stderr,"received reply for my search for route to %d , first hop %d\n",rt->rt_dst,rt->rt_nexthop);
                 Packet::free(p);
         }
 
@@ -1030,6 +1189,7 @@
 			 	(rt_dst->error_propagate_counter)++; // Mahesh 09/11/99
 #endif
        		     rp->rp_hop_count += 1;
+		     //fprintf(stderr,"%d is forwarding the reply\n",index);
                  forward(rt0, p, NO_DELAY);
             }
             else {
@@ -1115,7 +1275,7 @@
 
         if(ih->ttl_ == 0) {
 #ifdef DEBUG
-        fprintf(stderr, "%s: calling drop()\n", __PRETTY_FUNCTION__);
+        fprintf(stderr, "%s: calling drop() at node %d\n", __FUNCTION__,index);
 #endif
            drop(p, DROP_RTR_TTL);
            return;
@@ -1201,8 +1361,8 @@
 	 *  about sending out route requests. 
      */
 
-	if ((rt->rt_flags == RTF_UP) ||
-	    (rt->rt_req_timeout > CURRENT_TIME)) 
+	if (((rt->rt_flags == RTF_UP) ||
+	    (rt->rt_req_timeout > CURRENT_TIME)) && (!(rt->rt_warn)))
    		return;
       
 	// rt_req_cnt is the no. of times we did network-wide broadcast
@@ -1210,14 +1370,15 @@
 	// going to a long timeout.
 
 	if (rt->rt_req_cnt > RREQ_RETRIES) {
+	  //fprintf(stderr,"This is dangerous\n");
 		rt->rt_req_timeout = CURRENT_TIME + MAX_RREQ_TIMEOUT;
 		rt->rt_req_cnt = 0;
 		return;
 	}
 
 #ifdef DEBUG
-        fprintf(stderr, "(%2d) - %2d sending Route Request, dst: %d\n",
-                ++route_request, index, rt->rt_dst);
+        fprintf(stderr, "(%2d) - %2d sending Route Request, dst: %d with b_id %d\n",
+                ++route_request, index, rt->rt_dst,bid);
 #endif
 
 
@@ -1231,6 +1392,9 @@
     ch->addr_type() = NS_AF_NONE;
     ch->prev_hop_ = index;          // AODV hack
 
+    ch->warning_thresh()=PAThresh();
+    //fprintf(stderr,"this nodes threshold is %e\n",PAThresh());
+
     /*
     ih->src_ = index;
     ih->dst_ = IP_BROADCAST;
@@ -1248,6 +1412,7 @@
 
     if (0 == rt->rt_req_last_ttl) {
 	// first time query broadcast
+      //fprintf(stderr,"First TTL is used\n");
 		 ih->ttl_ = TTL_START;
 	}
 	else {
@@ -1282,10 +1448,10 @@
 
 #ifdef DEBUG
 	 fprintf(stderr, 
-	"(%2d) - %2d sending Route Request, dst: %d, tout %f ms\n",
+	"(%2d) - %2d sending Route Request, dst: %d, tout %f ms with b_id %d\n",
                 ++route_request, 
 		index, rt->rt_dst, 
-		rt->rt_req_timeout - CURRENT_TIME);
+		rt->rt_req_timeout - CURRENT_TIME,bid);
 #endif	
 	
 	// remember the TTL used  for the next time
@@ -1297,6 +1463,11 @@
     rq->rq_bcast_id = bid++;
     rq->rq_dst = dst;
     rq->rq_dst_seqno = (rt ? rt->rt_seqno : 0);
+
+    //added for proactivity, not to get old routes
+    if(rt && rt->rt_warn) rq->rq_dst_seqno++;
+    //fprintf(stderr,"I want the dest seq. no:%d\n",rq->rq_dst_seqno);
+
     rq->rq_src = index;
     rq->rq_src_seqno = seqno++; // Mahesh - 09/11/99
     rq->rq_timestamp = CURRENT_TIME;
@@ -1356,7 +1527,8 @@
 AODV::sendTriggeredReply(nsaddr_t ipdst, nsaddr_t rpdst, u_int32_t rpseq)
 {
 	// 08/28/98 - added this extra check
-	if(ipdst == 0 || ipdst == index) return;
+        // prevents sending back triggered reply to node 0
+  if(/*ipdst == 0 || */ipdst == index) return;
 
         Packet *p = Packet::alloc();
         struct hdr_cmn *ch = HDR_CMN(p);
@@ -1435,6 +1607,59 @@
 }
 #endif
 
+void
+AODV::sendWarn(nsaddr_t ipdst, u_int32_t hop_count, nsaddr_t rpdst,
+                u_int32_t rpseq, u_int32_t lifetime, nsaddr_t warn_dest)
+{
+  Packet *p = Packet::alloc();
+  struct hdr_cmn *ch = HDR_CMN(p);
+  struct hdr_ip *ih = HDR_IP(p);
+  struct hdr_aodv_warn *wr = HDR_AODV_WARN(p);
+
+  rt_entry *rt = rtable.rt_lookup(ipdst);
+
+  assert(rt);
+
+  // ch->uid() = 0;
+  ch->ptype() = PT_AODV;
+  ch->size() = IP_HDR_LEN + sizeof(*wr);
+
+  ch->iface() = -2;
+  ch->error() = 0;
+  ch->addr_type() = NS_AF_INET;
+
+  ch->next_hop_ = rt->rt_nexthop;
+  ch->prev_hop_ = index;          // AODV hack
+  ch->direction() = hdr_cmn::DOWN;
+
+  //no route warnings about this packet
+  ch->warning_thresh()=0.0;
+
+  /*
+    ih->src_ = index;
+    ih->dst_ = ipdst;
+    ih->sport_ = RT_PORT;
+    ih->dport_ = RT_PORT;
+  */
+  ih->saddr() = index;
+  ih->daddr() = ipdst;
+  ih->sport() = RT_PORT;
+  ih->dport() = RT_PORT;
+
+  ih->ttl_ = NETWORK_DIAMETER;
+
+  wr->rw_type = AODVTYPE_WARN;
+  wr->rw_hop_count = hop_count;
+
+  wr->rw_dst = ipdst;
+  wr->rw_dst_seqno = rpseq;
+  wr->rw_lifetime = lifetime;
+  wr->rw_warn_dest = warn_dest;
+
+  //fprintf(stderr,"%d is sending a warning to %d\n",index,ipdst);
+  //target_->recv(p, (Handler*) 0);
+  Scheduler::instance().schedule(target_, p, 0.);
+}
 
 void
 AODV::sendHello()
diff -u -b -N ns-2.1b6/aodv/aodv.h proactive-ns-2.1b6/aodv/aodv.h
--- ns-2.1b6/aodv/aodv.h	Mon Nov 29 23:25:32 1999
+++ proactive-ns-2.1b6/aodv/aodv.h	Fri Oct  3 00:09:23 2003
@@ -100,6 +100,8 @@
  * fully yet. Don't use it for now.
  */
 
+#define PRO_AODV
+
 class AODV;
 
 #define AODV_HDR_LEN    64      // amount of space allocated in the pkt hdr
@@ -255,6 +257,9 @@
          * HDR offsets
          */
         int             off_AODV_;
+#ifdef PRO_AODV
+  inline double& PAThresh() {return PAThresh_;}
+#endif
 
  protected:
         int             command(int, const char *const *);
@@ -269,6 +274,11 @@
  public:
         void            rt_ll_failed(Packet *p);
  protected:
+#ifdef PRO_AODV
+        int need_proactive_route_maintenance(Packet *p);
+        void do_proactive_route_maintenance(Packet *p);
+        void recvWarn(Packet *p);
+#endif
         void            rt_purge(void);
 
         void            enque(rt_entry *rt, Packet *p);
@@ -300,6 +310,9 @@
         void            sendReply(nsaddr_t ipdst, u_int32_t hop_count,
                                   nsaddr_t rpdst, u_int32_t rpseq,
                                   u_int32_t lifetime, double timestamp);
+        void            sendWarn(nsaddr_t ipdst, u_int32_t hop_count,
+				 nsaddr_t rpdst, u_int32_t rpseq,
+				 u_int32_t lifetime, nsaddr_t warn_dest);
         void            sendTriggeredReply(nsaddr_t ipdst,
 								nsaddr_t rpdst, u_int32_t rqseq);
 		// Overloaded to have the route error broadcast case
@@ -341,6 +354,9 @@
         RouteCacheTimer rtimer;
         LocalRepairTimer lrtimer;
 
+#ifdef PRO_AODV
+	double PAThresh_;
+#endif
 
         /*
          * Routing Table
diff -u -b -N ns-2.1b6/aodv/aodv_packet.h proactive-ns-2.1b6/aodv/aodv_packet.h
--- ns-2.1b6/aodv/aodv_packet.h	Mon Nov 29 23:25:32 1999
+++ proactive-ns-2.1b6/aodv/aodv_packet.h	Fri Oct  3 00:09:52 2003
@@ -13,6 +13,8 @@
 #define AODVTYPE_RREQ   0x02
 #define AODVTYPE_RREP   0x04
 #define AODVTYPE_UREP   0x08
+#define AODVTYPE_WARN 0x0F
+#define AODVTYPE_HACK 0x0A
 
 /*
  * AODV Routing Protocol Header Macros
@@ -20,6 +22,7 @@
 #define HDR_AODV(p)             ((struct hdr_aodv*)(p)->access(off_AODV_))
 #define HDR_AODV_REQUEST(p)     ((struct hdr_aodv_request*)(p)->access(off_AODV_))
 #define HDR_AODV_REPLY(p)       ((struct hdr_aodv_reply*)(p)->access(off_AODV_))
+#define HDR_AODV_WARN(p)        ((struct hdr_aodv_warn*)(p)->access(off_AODV_))
 
 /*
  * General AODV Header - shared by all formats
@@ -44,6 +47,17 @@
         double          rq_timestamp;           // when REQUEST sent
 };
 
+struct hdr_aodv_warn {
+        u_int8_t        rw_type;                // Packet Type
+        u_int8_t        reserved[2];
+        u_int8_t        rw_hop_count;           // Hop Count
+        nsaddr_t        rw_dst;                 // Destination IP Address
+        u_int32_t       rw_dst_seqno;           // Destination Sequence Number
+        u_int32_t       rw_lifetime;            // Lifetime
+  nsaddr_t        rw_warn_dest;           //the dest of the warned route link
+
+};
+
 struct hdr_aodv_reply {
         u_int8_t        rp_type;                // Packet Type
         u_int8_t        rp_flags;
diff -u -b -N ns-2.1b6/cmu-trace.cc proactive-ns-2.1b6/cmu-trace.cc
--- ns-2.1b6/cmu-trace.cc	Wed Jan 12 15:25:40 2000
+++ proactive-ns-2.1b6/cmu-trace.cc	Fri Oct  3 00:59:33 2003
@@ -298,7 +298,8 @@
 	   return;
 	}
 	sprintf(wrk_ + offset, 
-		"%d [%d %d] [%d %d %d %d->%d] [%d %d %d %d->%d]",
+		"%d [%d %d] [%d %d %d %d->%d] [%d %d %d %d->%d]"
+		" [%d %d %d %d->%d] %g",
 		srh->num_addrs(),
 
 		srh->route_request(),
@@ -315,7 +316,14 @@
 		srh->num_route_errors(),
 		srh->down_links()[srh->num_route_errors() - 1].tell_addr,
 		srh->down_links()[srh->num_route_errors() - 1].from_addr,
-		srh->down_links()[srh->num_route_errors() - 1].to_addr);
+		srh->down_links()[srh->num_route_errors() - 1].to_addr,
+
+		srh->route_warning(),
+		srh->num_route_warnings(),
+		srh->warn_links()[srh->num_route_warnings() - 1].tell_addr,
+		srh->warn_links()[srh->num_route_warnings() - 1].from_addr,
+		srh->warn_links()[srh->num_route_warnings() - 1].to_addr,
+		srh->warning_thresh());
 }
 
 void
@@ -479,6 +487,7 @@
         struct hdr_aodv *ah = HDR_AODV(p);
         struct hdr_aodv_request *rq = HDR_AODV_REQUEST(p);
         struct hdr_aodv_reply *rp = HDR_AODV_REPLY(p);
+	struct hdr_aodv_warn *wr=HDR_AODV_WARN(p);
 
         switch(ah->ah_type) {
         case AODVTYPE_RREQ:
@@ -542,6 +551,30 @@
 		}
                 break;
 
+	case AODVTYPE_WARN:
+		if (newtrace_) {
+
+		    sprintf(wrk_ + offset,
+			"-P aodv -Pc 0x%x -Ph %d -Pd %d -Pds %d -Pl %d -Pw %d WARN",
+			wr->rw_type,
+                        wr->rw_hop_count,
+                        wr->rw_dst,
+                        wr->rw_dst_seqno,
+                        wr->rw_lifetime,
+                            wr->rw_warn_dest);
+} else {
+
+		    sprintf(wrk_ + offset,
+			"[0x%x %d [%d %d] %d %d] (WARN)",
+			wr->rw_type,
+                        wr->rw_hop_count,
+                        wr->rw_dst,
+                        wr->rw_dst_seqno,
+                        wr->rw_lifetime,
+                        wr->rw_warn_dest);
+		}
+		break;
+
         default:
                 fprintf(stderr,
                         "%s: invalid AODV packet type\n", __FUNCTION__);
@@ -761,6 +794,8 @@
 void
 CMUTrace::recv(Packet *p, Handler *h)
 {
+	hdr_cmn *ch = HDR_CMN(p);
+
 	if (!node_energy()) {
 	    Packet::free(p);
 	    return;
@@ -792,8 +827,12 @@
                 God::instance()->stampPacket(p);
         }
 #endif
+
+	if(ch->hacked()==0)
+	{
 	format(p, "---");
 	dump();
+	}
 	//namdump();
 	if(target_ == 0)
 		Packet::free(p);
@@ -804,6 +843,7 @@
 void
 CMUTrace::recv(Packet *p, const char* why)
 {
+	hdr_cmn *ch = HDR_CMN(p);
 
         assert(initialized() && type_ == DROP);
 
@@ -823,8 +863,12 @@
                 God::instance()->stampPacket(p);
         }
 #endif
+
+	if(ch->hacked()==0)
+	{
 	format(p, why);
 	dump();
+	}
 	//namdump();
 	Packet::free(p);
 }
diff -u -b -N ns-2.1b6/dsr/dsragent.cc proactive-ns-2.1b6/dsr/dsragent.cc
--- ns-2.1b6/dsr/dsragent.cc	Mon Dec 20 16:34:14 1999
+++ proactive-ns-2.1b6/dsr/dsragent.cc	Thu Oct  2 14:08:37 2003
@@ -71,8 +71,8 @@
 /*==============================================================
   Declarations and global defintions
 ------------------------------------------------------------*/
-static const int verbose = 0;
-static const int verbose_srr = 0;
+static const int verbose = 1;
+static const int verbose_srr = 1;
 
 DSRAgent_List DSRAgent::agthead = { 0 };
 
@@ -99,7 +99,7 @@
 /*************** selectors ******************/
 bool dsragent_snoop_forwarded_errors = true;
 // give errors we forward to our cache?
-bool dsragent_snoop_source_routes = true;
+bool dsragent_snoop_source_routes = false;
 // should we snoop on any source routes we see?
 bool dsragent_reply_only_to_first_rtreq = false;
 // should we only respond to the first route request we receive from a host?
@@ -114,10 +114,10 @@
 // and salvage the packet using the route if possible
 bool dsragent_use_tap = true;
 // should we listen to a promiscuous tap?
-bool dsragent_reply_from_cache_on_propagating = true;
+bool dsragent_reply_from_cache_on_propagating = false;
 // should we consult the route cache before propagating rt req's and
 // answer if possible?
-bool dsragent_ring_zero_search = true;
+bool dsragent_ring_zero_search = false;
 // should we send a non-propagating route request as the first action
 // in each route discovery action?
 
@@ -145,6 +145,8 @@
 // route reply enough?
 #endif
 
+int proactive = 0;
+
 /*
 
 
@@ -339,6 +341,10 @@
   bind("off_mac_", &off_mac_);
   bind("off_ip_", &off_ip_);
 
+  bind("proactive_", &proactive);
+  bind("PAThresh_", &PAThresh_);
+  route_cache->default_warning_thresh() = PAThresh();
+
   LIST_INSERT_HEAD(&agthead, this, link);
   route_error_held = false;
 }
@@ -559,6 +565,12 @@
   p.dest = ID((Address::instance().get_nodeaddr(iph->daddr())),::IP);
   p.src = ID((Address::instance().get_nodeaddr(iph->saddr())),::IP);
 
+  if (proactive)
+  {
+    p.route.warning_thresh() = srh->warning_thresh();
+    p.route.rtreq_seq() = srh->rtreq_seq();
+  }
+
   assert(logtarget != 0);
   
   if (srh->valid() != 1) {
@@ -590,6 +602,13 @@
     {
        if (p.dest == net_id || p.dest == IP_broadcast)
 	      { // this packet is intended for us
+
+		      if (proactive && (p.dest != IP_broadcast) &&
+			  need_proactive_route_maintenance(p))
+		      {
+		        do_proactive_route_maintenance(p);
+		      }
+
 		      handlePacketReceipt(p);
 		      goto done;
 	      }
@@ -614,6 +633,11 @@
     }
   else
     { // we're not the intended final recpt, but we're a hop
+      if (proactive && need_proactive_route_maintenance(p))
+      {
+        do_proactive_route_maintenance(p);
+      }
+
       handleForwarding(p);
     }
     }
@@ -640,6 +664,7 @@
      this should be a retry if the packet is already in the sendbuffer */
 {
   hdr_sr *srh =  (hdr_sr*)p.pkt->access(off_sr_);
+  hdr_cmn *cmh =  (hdr_cmn*)p.pkt->access(off_cmn_);
   
   assert(srh->valid());
   if (p.dest == net_id)
@@ -664,18 +689,19 @@
   if (route_cache->findRoute(dest, p.route, 1))
     { // we've got a route...
       if (verbose)
-	trace("S$hit %.5f _%s_ %s -> %s %s",
+	trace("S$hit %.5f _%s_ %s -> %s %s %i",
 	      Scheduler::instance().clock(), net_id.dump(),
-	      p.src.dump(), dest.dump(), p.route.dump());      
+	      p.src.dump(), dest.dump(), p.route.dump(),
+	      cmh->uid());
       sendOutPacketWithRoute(p, true);
       return;
     } // end if we have a route
   else
     { // we don't have a route...
       if (verbose) 
-	trace("S$miss %.5f _%s_ %s -> %s", 
+	trace("S$miss %.5f _%s_ %s -> %s %i",
 	      Scheduler::instance().clock(), net_id.dump(), 
-	      net_id.dump(), p.dest.dump());
+	      net_id.dump(), p.dest.dump(), cmh->uid());
 
       getRouteForPacket(p, dest, retry);
       return;
@@ -717,6 +743,11 @@
 	    processBrokenRouteError(p);
     }
 
+  if (srh->route_warning())
+  {
+    processRouteWarning(p);
+  }
+
   /* give the data in the packet to our higher layer (our port dmuxer, most 
    likely) */
   handPktToDmux(p);
@@ -809,6 +840,21 @@
       return; // drop silently
     }
   
+  if (proactive)
+    assert(srh->warning_thresh() == route_cache->default_warning_thresh());
+
+  // ignore if receiver signal strength too low
+  if (proactive && (p.pkt->txinfo_.RxPr <= srh->warning_thresh()))
+  {
+    if (verbose_srr)
+      trace("SRR %.5f _%s_ dropped %s #%d (weak signal)",
+	    Scheduler::instance().clock(), net_id.dump(), p.src.dump(),
+	    srh->rtreq_seq());
+    Packet::free(p.pkt);
+    p.pkt = 0;
+    return;
+  }
+
   // we're going to process this request now, so record the req_num
   request_table.insert(p.src, p.src, srh->rtreq_seq());
 
@@ -967,6 +1013,13 @@
   // make up and send out a route reply
   p.route.appendToPath(net_id);
   p.route.reverseInPlace();
+
+  if (proactive)
+  {
+    p.route.warning_thresh() = route_cache->default_warning_thresh();
+    p.route.rtreq_seq() = request_seqnum;
+  }
+
   route_cache->addRoute(p.route, Scheduler::instance().clock(), net_id);
   p.dest = p.src;
   p.src = net_id;
@@ -1150,6 +1203,17 @@
   
   srh->init();
 
+  if (proactive)
+  {
+#if 0
+    rrp.route.warning_thresh() = p.route.warning_thresh();
+    srh->warning_thresh() = p.route.warning_thresh();
+#else
+    rrp.route.warning_thresh() = route_cache->default_warning_thresh();
+    srh->warning_thresh() = route_cache->default_warning_thresh();
+#endif
+  }
+
   if (BackOffTest(e, time))
     { // it's time to start another route request cycle
       if (dsragent_ring_zero_search)
@@ -1172,10 +1236,18 @@
    }
   else
     { // it's not time to send another route request...
+      /*
       if (!retry && verbose_srr)
 	trace("SRR %.5f _%s_ RR-not-sent %s -> %s", 
 	      Scheduler::instance().clock(), 
 	      net_id.dump(), rrp.src.dump(), rrp.dest.dump());
+      */
+      if (verbose_srr)
+	trace("SRR %.5f _%s_ RR-not-sent %s -> %s, requests outstanding %i, last type %s",
+	      Scheduler::instance().clock(),
+	      net_id.dump(), rrp.src.dump(), rrp.dest.dump(), e->rt_reqs_outstanding,
+	      (e->last_type == LIMIT0) ? "Ring-0" : "Unlimited");
+
       Packet::free(rrp.pkt); // dump the route request packet we made up
       rrp.pkt = 0;
       return;
@@ -1192,7 +1264,9 @@
   assert(srh->valid());
 
   srh->route_request() = 1;
-  srh->rtreq_seq() = route_request_num++;
+
+  p.route.rtreq_seq() = srh->rtreq_seq() = route_request_num++;
+
   srh->max_propagation() = max_prop;
   p.route.reset();
   p.route.appendToPath(net_id);
@@ -1323,6 +1397,9 @@
   if (p.route.full()) 
     return; // alas, the route would be to long once we add ourselves
 
+  if (p.pkt->txinfo_.RxPr <= route_cache->default_warning_thresh())
+    return;
+
   SRPacket p_copy = p;
   p_copy.pkt = allocpkt();
   p_copy.dest = p.src;
@@ -1360,8 +1437,14 @@
   // flip the route around for the return to the requestor, and 
   // cache the route for future use
   p_copy.route.reverseInPlace();
+
+  p_copy.route.warning_thresh() = route_cache->default_warning_thresh();
+  p_copy.route.rtreq_seq() = 0;
+
   route_cache->addRoute(p_copy.route, Scheduler::instance().clock(), net_id);
 
+  p_copy.route.rtreq_seq() = p.route.rtreq_seq();
+
   p_copy.route.resetIterator();
   p_copy.route.fillSR(new_srh);
   new_cmnh->size() += new_srh->size();
@@ -1408,6 +1491,8 @@
 	reply_route[reply_route.length()-1].dump(),
 	reply_route.dump());
 
+  reply_route.warning_thresh() = route_cache->default_warning_thresh();
+
   // add the new route into our cache
   route_cache->addRoute(reply_route, Scheduler::instance().clock(), p.src);
 
@@ -1443,11 +1528,13 @@
 		abort();
 	  }
 #endif
+	  hdr_cmn *cmh = (hdr_cmn*)send_buf[c].p.pkt->access(off_cmn_);
+
 	  if (verbose)
-	    trace("Sdebug %.9f _%s_ liberated from sendbuf %s->%s %s",
+	    trace("Sdebug %.9f _%s_ liberated from sendbuf %s->%s %s %i",
 		  Scheduler::instance().clock(), net_id.dump(),
 		  send_buf[c].p.src.dump(), send_buf[c].p.dest.dump(), 
-		  send_buf[c].p.route.dump());
+		  send_buf[c].p.route.dump(), cmh->uid());
 	  /* we need to spread out the rate at which we send packets
 	     in to the link layer to give ARP time to complete.  If we
 	     dump all the packets in at once, all but the last one will
@@ -1580,7 +1667,7 @@
       processBrokenRouteError(p);
     }
 
-  if (srh->route_reply())
+  if (dsragent_snoop_source_routes && srh->route_reply())
     {
       Path reply_path(srh->reply_addrs(), srh->route_reply_len());
       if(verbose)
@@ -1598,7 +1685,8 @@
   if (srh->route_request()) return; // don't path shorten route requests
   // the logic is wrong for shortening rtreq's anyway, cur_addr always = 0
 
-  if (dsragent_snoop_source_routes)
+  if (dsragent_snoop_source_routes &&
+      !(proactive && (srh->route_warning() || srh->warning_thresh() == 0.0)))
     {
       if (verbose)
 	trace("Sdebug _%s_ tap saw route use %d %s", net_id.dump(), 
@@ -1607,6 +1695,13 @@
 				   net_id);
     }
 
+  if (proactive && srh->route_warning())
+  {
+    if (verbose)
+      trace("Sdebug _%s_ tap saw warning %d",  net_id.dump(), cmh->uid());
+    processRouteWarning(p);
+  }
+
   if (PT_DSR == cmh->ptype()) return; //  no route shortening on any
   // DSR packet
 
@@ -1690,6 +1785,9 @@
 
   if (!dsragent_send_grat_replies) return;
 
+  if (p.pkt->txinfo_.RxPr <= route_cache->default_warning_thresh())
+    return;
+
   if (verbose)
     trace("Sdebug %s consider grat arp for %s", net_id.dump(), p.route.dump());
   GratReplyHoldDown *g = FindGratHoldDown(grat_hold, RTREP_HOLDOFF_SIZE, 
@@ -1742,6 +1840,9 @@
 	p_copy.src.dump(), p_copy.dest.dump(), p.route.length(), 
 	p.route.dump());
 
+  p_copy.route.warning_thresh() = route_cache->default_warning_thresh();
+  p_copy.route.rtreq_seq() = 0;
+
   // cache the route for future use (we learned the route from p)
   route_cache->addRoute(p_copy.route, Scheduler::instance().clock(), p.src);
   sendOutPacketWithRoute(p_copy, true);
@@ -1882,6 +1983,11 @@
 		Scheduler::instance().clock(), net_id.dump(),
 		p.src.dump(), p.dest.dump(), cmh->uid(), p.route.dump());
 
+	  // Don't do PA warning on salvaged pkts because source route
+	  // not from originator
+	  srh->warning_thresh() = 0.0;
+	  p.route.warning_thresh() = 0.0;
+
 	  sendOutPacketWithRoute(p, false);
 	}
       else
diff -u -b -N ns-2.1b6/dsr/dsragent.h proactive-ns-2.1b6/dsr/dsragent.h
--- ns-2.1b6/dsr/dsragent.h	Mon Nov 29 23:25:38 1999
+++ proactive-ns-2.1b6/dsr/dsragent.h	Thu Oct  2 13:55:56 2003
@@ -112,6 +112,8 @@
   DSRAgent();
   ~DSRAgent();
 
+  inline double& PAThresh() {return PAThresh_;}
+
 private:
 
   Trace *logtarget;
@@ -120,6 +122,8 @@
   int off_ip_;
   int off_sr_;
 
+  double PAThresh_;
+
   // will eventually need to handle multiple infs, but this is okay for
   // now 1/28/98 -dam
   ID net_id, MAC_id;		// our IP addr and MAC addr
@@ -236,6 +240,10 @@
   
 friend void RouteReplyHoldoffCallback(Node *node, Time time, EventData *data);
 #endif // 0
+
+  int need_proactive_route_maintenance(SRPacket &p);
+  void do_proactive_route_maintenance(SRPacket &p);
+  void processRouteWarning(SRPacket& p);
 
   /* the following variables are used to send end-of-sim notices to all objects */
 public:
diff -u -b -N ns-2.1b6/dsr/hdr_sr.cc proactive-ns-2.1b6/dsr/hdr_sr.cc
--- ns-2.1b6/dsr/hdr_sr.cc	Mon Dec 20 16:34:14 1999
+++ proactive-ns-2.1b6/dsr/hdr_sr.cc	Thu Oct  2 13:58:29 2003
@@ -77,5 +77,8 @@
       ptr += strlen(ptr);
     }
   *ptr++ = ']';
+
+  ptr += sprintf(ptr, " WT: %g", warning_thresh_);
+
   *ptr = '\0';
 }
diff -u -b -N ns-2.1b6/dsr/hdr_sr.h proactive-ns-2.1b6/dsr/hdr_sr.h
--- ns-2.1b6/dsr/hdr_sr.h	Mon Dec 20 21:39:39 1999
+++ proactive-ns-2.1b6/dsr/hdr_sr.h	Thu Oct  2 14:10:09 2003
@@ -63,6 +63,18 @@
   nsaddr_t to_addr;		// get packets to to_addr host
 };
 
+struct link_warn {
+  int addr_type;		/* same as hdr_cmn in packet.h */
+
+  nsaddr_t tell_addr;		// tell this host
+  nsaddr_t from_addr;		// that from_addr host may no longer
+  nsaddr_t to_addr;		// get packets to to_addr host
+
+  nsaddr_t dest_addr;		// final destination of packet
+};
+
+extern int proactive;
+
 struct hdr_sr {
   int valid_;			/* is this header actually in the packet? 
 				   and initialized? */
@@ -91,6 +103,12 @@
   int num_route_errors_;
   struct link_down down_links_[MAX_ROUTE_ERRORS];
 
+#define MAX_ROUTE_WARNINGS 1
+  int route_warning_;
+  int num_route_warnings_;
+  struct link_warn warn_links_[MAX_ROUTE_WARNINGS];
+  double warning_thresh_;
+
   static int offset_;		/* offset for this header */
   inline int& offset() { return offset_; }
 
@@ -110,6 +128,11 @@
   inline int& num_route_errors() {return num_route_errors_;}
   inline struct link_down* down_links() {return down_links_;}
 
+  inline int& route_warning() {return route_warning_;}
+  inline int& num_route_warnings() {return num_route_warnings_;}
+  inline struct link_warn* warn_links() {return warn_links_;}
+  inline double& warning_thresh() {return warning_thresh_;}
+
   inline nsaddr_t& get_next_addr() { 
     assert(cur_addr_ < num_addrs_);
     return (addrs[cur_addr_ + 1].addr); }
@@ -131,13 +154,24 @@
     route_reply_ = 0;
     route_reply_len_ = 0;
     route_error_ = 0;
-    num_route_errors_ = 0;}
+    num_route_errors_ = 0;
+
+    route_warning_ = 0;
+    num_route_warnings_ = 0;
+    warning_thresh_ = 0.0;
+    rtreq_seq_ = 0;
+  }
 
   inline int size() { 
 	int sz = SR_HDR_SZ +
 		 4 * (num_addrs_ - 1) +
 		 4 * (route_reply_ ? route_reply_len_ : 0) +
 		 8 * (route_error_ ? num_route_errors_ : 0);
+
+	// make this more realistic
+	if (proactive)
+		sz += 4 + 10 * (route_warning_ ? num_route_warnings_ : 0);
+
 	assert(sz >= 0);
 	return sz;
   }
diff -u -b -N ns-2.1b6/dsr/mobicache.cc proactive-ns-2.1b6/dsr/mobicache.cc
--- ns-2.1b6/dsr/mobicache.cc	Mon Dec 20 16:34:14 1999
+++ proactive-ns-2.1b6/dsr/mobicache.cc	Thu Oct  2 20:35:01 2003
@@ -53,6 +53,7 @@
 #include <dsr/cache_stats.h>
 #endif
 
+extern int proactive;
 
 /* invariants
 
@@ -62,7 +63,7 @@
 
 #define fout stdout
 
-static const int verbose = 1;
+static const int verbose = 0;
 static const int verbose_debug = 0;
 
 /*===============================================================
@@ -98,6 +99,8 @@
   // the link from->to isn't working anymore, purge routes containing
   // it from the cache
 
+  Path* get_cache_line(Path& route);
+
 private:
   Path *cache;
   int size;
@@ -133,6 +136,13 @@
   // already
   int command(int argc, const char*const* argv);
 
+  int countRoutes(const ID& dest, bool use_secondary = false);
+  Path *get_cache_line(Path& route, bool primary = true);
+  bool pafindRoute(ID dest, Path& route, int for_me);
+  bool nopafindRoute(ID dest, Path& route, int for_me);
+  void noticeWarnLink(const ID& tell, const ID& from, const ID& to);
+  inline double& default_warning_thresh() {return default_warning_thresh_;}
+
 protected:
   Cache *primary_cache;   /* routes that we are using, or that we have reason
 			    to believe we really want to hold on to */
@@ -144,6 +154,9 @@
   void checkRoute(Path *p, int action, int prefix_len);
   void checkRoute(Path &p, int&, int&, double&, int&, int&);
 #endif
+
+private:
+  double default_warning_thresh_;
 };
 
 
@@ -299,6 +312,60 @@
   if(pre_addRoute(route, rt, t, who_from) == 0)
     return;
 
+  //  If this route is already in the secondary cache,
+  //  don't put it in the primary cache
+  // FIX: unless from a new route discovery cycle
+#if 0
+  if (proactive && (secondary_cache->get_cache_line(rt) != NULL))
+    return;
+#endif
+
+  if (proactive)
+  {
+    Path p;
+    int len, already_have_shorter_route = 0, hit = 0;
+    ID dest = rt[rt.length() - 1];
+
+    // Check primary cache for route to dest
+    for (int i = 0; primary_cache->searchRoute(dest, len, p, i); i++)
+    {
+      assert(hit == 0);		// only one route to dest in cache at a time
+      hit = 1;
+
+      if (len + 1 < rt.length())
+	already_have_shorter_route = 1;
+      else
+      {
+	// remove longer cached route
+	if (verbose_debug)
+	  trace("SRC %.9f _%s_ new route, primary removing %s",
+		Scheduler::instance().clock(), net_id.dump(),
+		primary_cache->cache[i].dump());
+
+	primary_cache->cache[i].reset();
+      }
+    }
+
+    // Check if a shorter route is already cached
+    if (already_have_shorter_route)
+      return;
+
+    // this new route will be added to the cache, so remove any
+    // routes to dest in secondary cache
+    for (int i = 0; secondary_cache->searchRoute(dest, len, p, i); i++)
+    {
+      assert(hit == 0);		// only one route to dest in cache at a time
+      hit = 1;
+
+      if (verbose_debug)
+	trace("SRC %.9f _%s_ new route, secondary removing %s",
+	      Scheduler::instance().clock(), net_id.dump(),
+	      secondary_cache->cache[i].dump());
+
+      secondary_cache->cache[i].reset();
+    }
+  }
+
   // must call addRoute before checkRoute
   int prefix_len = 0;
 
@@ -325,6 +392,66 @@
   return;
 }
 
+void MobiCache::noticeWarnLink(const ID& tell, const ID& from, const ID& to)
+{
+  assert(proactive);
+
+  if(verbose_debug)
+    trace("SRC %.9f _%s_ warn link %s->%s",
+	  Scheduler::instance().clock(), net_id.dump(),
+	  from.dump(), to.dump());
+
+  // demote routes that use the named link from primary cache to
+  // secondary cache
+  for (int p = 0; p < primary_cache->size; p++)
+  {// for all paths in the cache
+    for (int n = 0; n < primary_cache->cache[p].length() - 1; n++)
+    {// for all nodes in the path
+      if ((primary_cache->cache[p][n] == from) && (primary_cache->cache[p][n + 1] == to))
+      {
+	if(verbose_debug)
+	  trace("SRC %.9f _%s_ %s demoting %s",
+		Scheduler::instance().clock(),
+		net_id.dump(),
+		primary_cache->name, primary_cache->cache[p].dump());
+
+	// add to secondary cache
+	int prefix_len = 0;
+	secondary_cache->addRoute(primary_cache->cache[p], prefix_len);
+
+	// remove from primary cache
+	primary_cache->cache[p].reset();
+	break;
+      }
+    }
+  }
+
+  // If the warning is for us, set warning threshold to 0.0 for all
+  // routes in secondary cache that use this link
+  if (tell == net_id)
+  {
+    for (int p = 0; p < secondary_cache->size; p++)
+    {// for all paths in the cache
+      for (int n = 0; n < secondary_cache->cache[p].length() - 1; n++)
+      {// for all nodes in the path
+	if ((secondary_cache->cache[p][n] == from) && (secondary_cache->cache[p][n + 1] == to))
+	{
+	  secondary_cache->cache[p].warning_thresh() = 0.0;
+
+	  if(verbose_debug)
+	    trace("SRC %.9f _%s_ %s zeroing wt %s",
+		  Scheduler::instance().clock(),
+		  net_id.dump(),
+		  secondary_cache->name, secondary_cache->cache[p].dump());
+
+	  break;
+	}
+      }
+    }
+  }
+
+  return;
+}
 
 void
 MobiCache::noticeRouteUsed(const Path& p, Time t, const ID& who_from)
@@ -336,6 +463,13 @@
 
   int prefix_len = 0;
 
+  if (proactive)
+  {
+    stub.warning_thresh() = default_warning_thresh();
+    Path& p2 = (Path&) p;
+    stub.rtreq_seq() = p2.rtreq_seq();
+  }
+
 #ifdef DSR_CACHE_STATS
   Path *p0 = secondary_cache->addRoute(stub, prefix_len);
   checkRoute(p0, ACTION_NOTICE_ROUTE, prefix_len);
@@ -344,8 +478,18 @@
 #endif
 }
 
+bool MobiCache::findRoute(ID dest, Path& route, int for_me)
+{
+#if 1
+  return (proactive) ? pafindRoute(dest, route, for_me) :
+    nopafindRoute(dest, route, for_me);
+#else
+  return nopafindRoute(dest, route, for_me);
+#endif
+}
+
 bool
-MobiCache::findRoute(ID dest, Path& route, int for_me)
+MobiCache::nopafindRoute(ID dest, Path& route, int for_me)
 // if there is a cached path from us to dest returns true and fills in
 // the route accordingly. returns false otherwise
 // if for_me, then we assume that the node really wants to keep 
@@ -450,6 +594,107 @@
     }
 }
 
+bool MobiCache::pafindRoute(ID dest, Path& route, int for_me)
+{
+  Path primary_path, secondary_path, path;
+  int primary_path_len, secondary_path_len, len, p_hit, s_hit;
+
+  assert(proactive);
+
+  p_hit = s_hit = 0;
+
+  // NOTE: because of use, these length variables equal actual
+  //       route length minus one
+  primary_path_len = secondary_path_len = MAX_SR_LEN + 1;
+
+  assert(!(net_id == invalid_addr));
+
+  // search primary cache
+  for (int i = 0; primary_cache->searchRoute(dest, len, path, i); i++)
+  {
+    p_hit = 1;
+    if (len < primary_path_len)
+    {
+      primary_path = path;
+      primary_path_len = len;
+    }
+  }
+
+  // FIX
+#if 1
+  if (for_me)
+#endif
+    for (int i = 0; secondary_cache->searchRoute(dest, len, path, i); i++)
+    {
+      s_hit = 1;
+      if (len < secondary_path_len)
+      {
+	secondary_path = path;
+	secondary_path_len = len;
+      }
+    }
+
+  if ((verbose_debug) && (p_hit || s_hit))
+    trace("SRC PA %.9f _%s_ $hit for %s in %s %s",
+	  Scheduler::instance().clock(), net_id.dump(),
+	  dest.dump(), p_hit ? "primary" : "secondary",
+	  p_hit ? primary_path.dump(): secondary_path.dump());
+
+  // FIX: Should primary paths always be preferred??
+  if (p_hit)
+  {
+    route = primary_path;
+    route.setLength(primary_path_len + 1);
+    return true;
+  }
+  else if (s_hit)
+  {
+    route = secondary_path;
+    route.setLength(secondary_path_len + 1);
+    return true;
+  }
+  else
+  {
+    // no route found
+
+    if (verbose_debug)
+      trace("SRC PA %.9f _%s_ find-route [%d] %s->%s miss %d %.9f",
+	    Scheduler::instance().clock(), net_id.dump(),
+	    0, net_id.dump(), dest.dump(), 0, 0.0);
+
+    return false;
+  }
+}
+
+int MobiCache::countRoutes(const ID& dest, bool use_secondary = false)
+{
+  Path path;
+  int len, count = 0;
+
+  assert(proactive);
+
+  for (int i = 0; primary_cache->searchRoute(dest, len, path, i); i++)
+    count++;
+
+  if (use_secondary)
+  {
+    for (int i = 0; secondary_cache->searchRoute(dest, len, path, i); i++)
+      count++;
+  }
+
+  assert(count <= 1);
+
+  return count;
+}
+
+Path* MobiCache::get_cache_line(Path& route, bool primary = true)
+{
+  assert(proactive);
+
+  Cache *cache = (primary) ? primary_cache : secondary_cache;
+  return cache->get_cache_line(route);
+}
+
 /*===========================================================================
   class Cache routines
 ---------------------------------------------------------------------------*/
@@ -490,6 +735,15 @@
   int index, m, n;
   int victim;
 
+  // If route is already in the cache don't set the warning
+  // threshold (leave it as is)
+  if (proactive)
+  {
+    Path *cached_route;
+    if ((cached_route = get_cache_line(path)) != NULL)
+      path.warning_thresh() = cached_route->warning_thresh();
+  }
+
   // see if this route is already in the cache
   for (index = 0 ; index < size ; index++)
     { // for all paths in the cache
@@ -507,6 +761,14 @@
 	    routecache->trace("SRC %.9f _%s_ %s suffix-rule (len %d/%d) %s",
    	      Scheduler::instance().clock(), routecache->net_id.dump(),
               name, n, path.length(), path.dump());	
+
+	  // FIX: This might not be right
+	  if (proactive)
+	  {
+	    cache[index].warning_thresh() = path.warning_thresh();
+	    cache[index].rtreq_seq() = path.rtreq_seq();
+	  }
+
 	  goto done;
 	}
       else if (n == path.length())
@@ -533,11 +795,27 @@
 		      Scheduler::instance().clock(), routecache->net_id.dump(),
 		      path.dump());	
   }
+
+  // if removing from primary cache, move victim to secondary cache
+#if 0
+  if (proactive && (strcmp(name, "primary") == 0))
+  {
+    int prefix_len = 0;
+    routecache->secondary_cache->addRoute(cache[victim], prefix_len);
+  }
+#endif
+
   cache[victim].reset();
   CopyIntoPath(cache[victim], path, 0, path.length() - 1);
   common_prefix_len = 0;
   index = victim; // remember which cache line we stuck the path into
 
+  if (proactive)
+  {
+    cache[index].warning_thresh() = path.warning_thresh();
+    cache[index].rtreq_seq() = path.rtreq_seq();
+  }
+
 done:
 
 #ifdef DEBUG
@@ -663,6 +941,35 @@
                     cache[victim].length() - 1, bad, name);
 #endif
   return victim;
+}
+
+Path* Cache::get_cache_line(Path& route)
+{
+  assert(proactive);
+
+  // for all cache entries
+  for (int i = 0; i < size; i++)
+  {
+    int j;
+
+    // check if cache entry is long enough to hold route
+    if (route.length() > cache[i].length())
+      continue;
+
+    // Check if route is a sub-path of cache entry
+    for (j = 0; j < route.length(); j++)
+    {
+      if (cache[i][j] != route[j])
+	break;
+    }
+
+    // looks like a match
+    if (j == route.length())
+      return &cache[i];
+  }
+
+  // no match found
+  return NULL;
 }
 
 #ifdef DSR_CACHE_STATS
diff -u -b -N ns-2.1b6/dsr/path.cc proactive-ns-2.1b6/dsr/path.cc
--- ns-2.1b6/dsr/path.cc	Mon Dec 20 16:34:14 1999
+++ proactive-ns-2.1b6/dsr/path.cc	Thu Oct  2 13:59:06 2003
@@ -113,6 +113,9 @@
       len = 0;
     }
   cur_index = 0;
+
+  warning_thresh_ = 0.0;
+  rtreq_seq_ = 0;
 }
 
 Path::Path()
@@ -120,6 +123,9 @@
   path = new ID[MAX_SR_LEN];
   len = 0;
   cur_index = 0;
+
+  warning_thresh_ = 0.0;
+  rtreq_seq_ = 0;
 }
 
 
@@ -133,12 +139,18 @@
 
   this->len = len;
   cur_index = 0;
+
+  warning_thresh_ = 0.0;
+  rtreq_seq_ = 0;
 }
 
 Path::Path(const struct hdr_sr *srh)
 { /* make a path from the bits of an NS source route header */
   path = new ID[MAX_SR_LEN];
 
+  warning_thresh_ = srh->warning_thresh_;
+  rtreq_seq_ = srh->rtreq_seq_;
+
   if (srh->valid_ != 1)
     {
       len = 0;
@@ -164,6 +176,9 @@
     }
   srh->num_addrs() = len;
   srh->cur_addr() = cur_index;
+
+  srh->warning_thresh() = warning_thresh_;
+  srh->rtreq_seq() = rtreq_seq_;
 }
 
 Path::Path(const Path& old)
@@ -181,6 +196,9 @@
     }
   cur_index = old.cur_index;
   path_owner = old.path_owner;
+
+  warning_thresh_ = old.warning_thresh_;
+  rtreq_seq_ = old.rtreq_seq_;
 }
 
 Path::~Path()
@@ -215,6 +233,9 @@
       len = rhs.len;
       for (int c = 0 ; c < len ; c++)
 	path[c] = rhs.path[c];
+
+      warning_thresh_ = rhs.warning_thresh_;
+      rtreq_seq_ = rhs.rtreq_seq_;
     }
   // note: i don't return *this cause I don't think assignments should
   // be expressions (and it has slightly incorrect semantics: (a=b) should
@@ -279,6 +300,9 @@
   for (int c = 0 ; c < len ; c++)
     to.path[c] = path[c];  
   to.path_owner = path_owner;
+
+  to.warning_thresh_ = warning_thresh_;
+  to.rtreq_seq_ = rtreq_seq_;
 }
 
 Path
@@ -379,6 +403,10 @@
       ptr += strlen(ptr);
     }
   *ptr++ = ']';
+
+  ptr += sprintf(ptr," WT: %g rtreq_seq: %i",
+		 warning_thresh_, rtreq_seq_);
+
   *ptr++ = '\0';
   return rtn_buf;
 }
diff -u -b -N ns-2.1b6/dsr/path.h proactive-ns-2.1b6/dsr/path.h
--- ns-2.1b6/dsr/path.h	Mon Nov 29 23:25:38 1999
+++ proactive-ns-2.1b6/dsr/path.h	Thu Oct  2 13:59:35 2003
@@ -152,11 +152,18 @@
   inline ID &owner() {return path_owner;}
 
   void checkpath(void) const;
+
+  inline double& warning_thresh() {return warning_thresh_;}
+  inline int& rtreq_seq() {return rtreq_seq_;}
+
 private:
   int len;
   int cur_index;
   ID* path;
   ID path_owner;
+
+  double warning_thresh_;
+  int rtreq_seq_;
 };
 
 void compressPath(Path& path);
diff -u -b -N ns-2.1b6/dsr/proactive.cc proactive-ns-2.1b6/dsr/proactive.cc
--- ns-2.1b6/dsr/proactive.cc	Wed Dec 31 19:00:00 1969
+++ proactive-ns-2.1b6/dsr/proactive.cc	Thu Oct  2 14:00:42 2003
@@ -0,0 +1,253 @@
+#include <packet.h>
+
+#include "dsragent.h"
+#include "packet-stamp.h"
+#include "hdr_sr.h"
+#include "routecache.h"
+#include <address.h>
+
+static const int pa_verbose = 1;
+extern int proactive;
+
+static void patrace(Trace *logtarget, char* fmt, ...);
+
+#define CREATE_SR_PKT(p, psrc, pdest) \
+  assert(psrc == net_id); \
+  SRPacket p; \
+  p.dest = pdest; \
+  p.src = psrc; \
+  p.pkt = allocpkt(); \
+  hdr_sr *p##_srh =  (hdr_sr*)p.pkt->access(off_sr_); \
+  hdr_ip *p##_iph =  (hdr_ip*)p.pkt->access(off_ip_); \
+  hdr_cmn *p##_cmnh =  (hdr_cmn*)p.pkt->access(off_cmn_); \
+  p##_iph->daddr() = Address::instance().create_ipaddr(pdest.getNSAddr_t(), RT_PORT); \
+  p##_iph->dport() = RT_PORT; \
+  p##_iph->saddr() = Address::instance().create_ipaddr(psrc.getNSAddr_t(), RT_PORT); \
+  p##_iph->sport() = RT_PORT; \
+  p##_iph->ttl() = 255; \
+  p##_cmnh->ptype() = PT_DSR; \
+  p##_cmnh->size() = size_ + IP_HDR_LEN; \
+  p##_cmnh->num_forwards() = 0; \
+  p##_srh->init();
+
+int DSRAgent::need_proactive_route_maintenance(SRPacket &p)
+{
+  Packet *pkt = p.pkt;
+  hdr_sr *srh = (hdr_sr*)pkt->access(off_sr_);
+  hdr_ip *iph = (hdr_ip*)pkt->access(off_ip_);
+  hdr_cmn *cmh = (hdr_cmn*)pkt->access(off_cmn_);
+
+  double TxPr = pkt->txinfo_.getTxPr();
+  double RXThresh = pkt->txinfo_.RXThresh;
+
+  assert(cmh->size() >= 0);
+  assert(proactive);
+
+  // Only do pro-active maintenance if this is a data packet
+  if (!DATA_PACKET(cmh->ptype()))
+      return 0;
+
+  if ((pa_verbose) && (logtarget))
+    patrace(logtarget, "SCheckingSignalStrength %.9f _%s_ %d %d %s %s %i->%s "
+	    "%g %g %g %s",
+	    Scheduler::instance().clock(), net_id.dump(),
+	    cmh->uid(), cmh->ptype(),
+	    p.src.dump(),
+	    p.dest.dump(),
+	    srh->addrs[srh->cur_addr() - 1].addr, net_id.dump(),
+	    TxPr, pkt->txinfo_.RxPr, RXThresh,
+	    p.route.dump());
+
+  return (pkt->txinfo_.RxPr <= srh->warning_thresh()) ? 1 : 0;
+}
+
+void DSRAgent::do_proactive_route_maintenance(SRPacket &p)
+{
+  Packet *pkt = p.pkt;
+  hdr_sr *srh = (hdr_sr*)pkt->access(off_sr_);
+  hdr_cmn *cmh = (hdr_cmn*)pkt->access(off_cmn_);
+
+  assert(cmh->size() >= 0);
+  assert(proactive);
+
+  // Source Route header is valid
+  assert(srh->valid());
+
+  // This must be a data packet
+  assert(DATA_PACKET(cmh->ptype()));
+
+  // The packet is for us
+  bool ForUs = (p.dest == net_id) || (p.dest == MAC_id);
+
+  // We're the ``current'' host along the source route
+  bool CurrentHost = (p.route[p.route.index()] == net_id) ||
+    (p.route[p.route.index()] == MAC_id);
+
+  assert(ForUs || CurrentHost);
+
+  // This shouldn't happen -- would only happen if we received
+  // something we transmitted.
+  if (p.src == net_id || p.src == MAC_id)
+  { // no need to send the route warning if it's for us
+    if (pa_verbose)
+      trace("Sdebug _%s_ not bothering to send route warning to ourselves",
+	    p.src.dump());
+    return;
+  }
+
+#if 0 // This doesn't matter for now
+  if (srh->num_route_warnings() >= MAX_ROUTE_WARNINGS)
+  { // no more room in the error packet to nest an additional error.
+    // this pkt's been bouncing around so much, let's just drop and let
+    // the originator retry
+    // Another possibility is to just strip off the outer error, and
+    // launch a Route discovey for the inner error XXX -dam 6/5/98
+    trace("SDFU  %.5f _%s_ dumping maximally nested warning %s  %d -> %d",
+	  Scheduler::instance().clock(), net_id.dump(),
+	  p.src..dump(),
+	  from_id.dump(),
+	  net_id.dump());
+    return;
+  }
+#endif
+
+  // Create the Route warning packet to send back
+  CREATE_SR_PKT(p_copy, net_id, p.src);
+
+  // Copy path (up to this node) from recved pkt into outgoing packet
+  CopyIntoPath(p_copy.route, p.route, 0, p.route.index());
+
+  // reverse path to get back to originator
+  p_copy.route.reverseInPlace();
+
+  // set up source route in packet header
+  p_copy.route.resetIterator();
+  p_copy.route.fillSR(p_copy_srh);
+
+  // no route warnings about this packet
+  p_copy_srh->warning_thresh() = 0.0;
+  p_copy.route.warning_thresh() = 0.0;
+
+  link_warn *warnlink =
+    &(p_copy_srh->warn_links()[p_copy_srh->num_route_warnings()]);
+
+  warnlink->addr_type = srh->addrs[srh->cur_addr()].addr_type;
+  warnlink->from_addr = srh->addrs[srh->cur_addr() - 1].addr;
+  warnlink->to_addr = srh->addrs[srh->cur_addr()].addr;
+  warnlink->tell_addr = srh->addrs[0].addr;
+  warnlink->dest_addr = srh->addrs[srh->num_addrs() - 1].addr;
+  p_copy_srh->num_route_warnings() += 1;
+  p_copy_srh->rtreq_seq() = 0;
+  p_copy_srh->route_warning() = 1;
+
+  ID test_from_id(p_copy_srh->addrs[p_copy_srh->cur_addr()].addr, (ID_Type)
+		  p_copy_srh->addrs[p_copy_srh->cur_addr()].addr_type);
+
+  assert(test_from_id == net_id || test_from_id == MAC_id);
+
+  patrace(logtarget, "SSendWarning %.9f _%s_ %d %d %s %s %s %s",
+	Scheduler::instance().clock(), net_id.dump(),
+	p_copy_cmnh->uid(), p_copy_cmnh->ptype(),
+	p.src.dump(),
+	p.dest.dump(),
+	p_copy_srh->dump(),	// warning source route
+	p.route.dump());	// original pkt source route
+
+  /* send out the Route Warning message */
+  sendOutPacketWithRoute(p_copy, false);
+
+  // Lower warning threshold in original packet (avoid duplicate
+  // warnings along same path when forwarding)
+  srh->warning_thresh() = 0.0;
+  p.route.warning_thresh() = 0.0;
+
+  return;
+}
+
+void DSRAgent::processRouteWarning(SRPacket& p)
+{
+  Packet *pkt = p.pkt;
+  hdr_sr *srh = (hdr_sr*)pkt->access(off_sr_);
+  hdr_ip *iph = (hdr_ip*)pkt->access(off_ip_);
+  hdr_cmn *cmh = (hdr_cmn*)pkt->access(off_cmn_);
+
+  assert(proactive);
+  assert(cmh->size() >= 0);
+  assert(srh->route_warning());
+  assert(srh->num_route_warnings() > 0);
+
+  for (int i = 0; i < srh->num_route_warnings(); i++)
+  {
+    link_warn *warnlink = &(srh->warn_links()[i]);
+
+    ID tell_id(warnlink->tell_addr, (ID_Type)warnlink->addr_type);
+    ID from_id(warnlink->from_addr, (ID_Type)warnlink->addr_type);
+    ID to_id(warnlink->to_addr, (ID_Type)warnlink->addr_type);
+    ID dest_id(warnlink->dest_addr, (ID_Type)warnlink->addr_type);
+
+    // count how many routes to dest are left in primary cache
+    int primary_routes = route_cache->countRoutes(dest_id, false);
+
+    route_cache->noticeWarnLink(tell_id, from_id, to_id);
+
+    // if the warning is for us, do proactive maintenance
+    if ((tell_id == net_id) && (primary_routes > 0)) // don't already know about warning
+    {
+      // count how many routes to dest are left in primary cache
+      // (after demoting)
+      primary_routes = route_cache->countRoutes(dest_id, false);
+
+      if (primary_routes == 0)
+      {
+	// Need to create a fake packet to get route for.  A `true' 2nd
+	// parameter in getRouteForPacket() will make sure the packet is not
+	// really sent
+
+	CREATE_SR_PKT(fake_p, net_id, dest_id);
+
+	if (pa_verbose)
+	  patrace(logtarget, "SSendingPARouteDisc %.9f _%s_ %d %d %s -> %s",
+		Scheduler::instance().clock(), net_id.dump(),
+		fake_p_cmnh->uid(), fake_p_cmnh->ptype(),
+		net_id.dump(), dest_id.dump());
+
+	fake_p.route.warning_thresh() = route_cache->default_warning_thresh();
+	fake_p_srh->warning_thresh() = route_cache->default_warning_thresh();
+
+#if 1
+	getRouteForPacket(fake_p, fake_p.dest, true);
+#else
+	Entry *e = request_table.getEntry(p.dest);
+	Time time = Scheduler::instance().clock();
+
+	if (BackOffTest(e, time))
+	{
+	  e->last_type = UNLIMIT;
+	  sendOutRtReq(fake_p, MAX_SR_LEN);
+	  e->last_arp = time;
+	}
+	else
+	{
+	  Packet::free(fake_p.pkt); // dump the route request packet we made up
+	  fake_p.pkt = 0;
+	}
+#endif
+      }
+    }
+  }
+
+  return;
+}
+
+static void patrace(Trace *logtarget, char* fmt, ...)
+{
+  va_list ap;
+
+  if (logtarget == NULL)
+    return;
+
+  va_start(ap, fmt);
+  vsprintf(logtarget->buffer(), fmt, ap);
+  logtarget->dump();
+  va_end(ap);
+}
diff -u -b -N ns-2.1b6/dsr/routecache.h proactive-ns-2.1b6/dsr/routecache.h
--- ns-2.1b6/dsr/routecache.h	Mon Nov 29 23:25:39 1999
+++ proactive-ns-2.1b6/dsr/routecache.h	Thu Oct  2 20:42:56 2003
@@ -88,6 +88,11 @@
   void trace(char* fmt, ...);
 
 ///////////////////////////////////////////////////////////////////////////
+
+  virtual int countRoutes(const ID& dest, bool use_secondary = false) = 0;
+  virtual double& default_warning_thresh() = 0;
+  virtual Path *get_cache_line(Path& route, bool primary = true) = 0;
+  virtual void noticeWarnLink(const ID& tell, const ID& from, const ID& to) = 0;
 
   int pre_addRoute(const Path& route, Path &rt,
 		   Time t, const ID& who_from);
diff -u -b -N ns-2.1b6/ll.cc proactive-ns-2.1b6/ll.cc
--- ns-2.1b6/ll.cc	Mon Nov 29 23:25:03 1999
+++ proactive-ns-2.1b6/ll.cc	Fri Oct  3 01:05:00 2003
@@ -44,6 +44,8 @@
 #include <ll.h>
 #include <address.h>
 #include <dsr/hdr_sr.h>
+#include <aodv/aodv_packet.h>
+#include <aodv/aodv.h>
 
 int hdr_ll::offset_;
 
@@ -229,16 +231,58 @@
 	}
 }
 
+Packet* LL::FakePacket(Packet* pp)
+{
+	Packet *p = Packet::alloc();
+	struct hdr_cmn *ch = HDR_CMN(p);
+	struct hdr_ip *ih = HDR_IP(p);
+
+	struct hdr_cmn *chpp = HDR_CMN(pp);
+	struct hdr_ip *ihpp = HDR_IP(pp);
+
+	// ch->uid() = 0;
+	ch->ptype() = PT_AODV;
+	ch->hacked()=1;
+	ch->size() = IP_HDR_LEN;
+
+	ch->iface() = chpp->iface();
+	ch->error() = chpp->error();
+	ch->addr_type() = chpp->addr_type();
+
+	ch->next_hop_ = chpp->next_hop_;
+	ch->prev_hop_ = chpp->prev_hop_; // AODV hack
+	ch->direction() = chpp->direction();
+
+	//no route warnings about this packet
+	ch->warning_thresh()=chpp->warning_thresh();
+	// fprintf(stderr,"Just copying old:%e , new:%e\n",chpp->warning_thresh(),ch->warning_thresh());
+
+	//copy the last receive signal
+	p->txinfo_.RxPr=pp->txinfo_.RxPr;
+
+	ih->saddr() = ihpp->saddr();
+	ih->daddr() = ihpp->daddr();
+	ih->sport() = RT_PORT;
+	ih->dport() = RT_PORT;
 
+	ih->ttl_ = ihpp->ttl_;
+	return p;
+}
 
 void LL::sendUp(Packet* p)
 {
 
 	Scheduler& s = Scheduler::instance();
+	hdr_cmn *ch = HDR_CMN(p);
+
 	if (hdr_cmn::access(p)->error() > 0)
 		drop(p);
 	else
+	{
 		s.schedule(uptarget_, p, delay_);
+		if( ch->ptype() != PT_AODV)
+			s.schedule(uptarget_,FakePacket(p), delay_);
+	}
 }
 
 
diff -u -b -N ns-2.1b6/ll.h proactive-ns-2.1b6/ll.h
--- ns-2.1b6/ll.h	Mon Nov 29 23:25:03 1999
+++ proactive-ns-2.1b6/ll.h	Fri Oct  3 01:17:02 2003
@@ -89,6 +89,7 @@
 
 	virtual void sendUp(Packet* p);
 	virtual void sendDown(Packet* p);
+	Packet* LL::FakePacket(Packet* pp);
 	
 	inline int seqno() { return seqno_; }
 	inline int ackno() { return ackno_; }
diff -u -b -N ns-2.1b6/packet-stamp.h proactive-ns-2.1b6/packet-stamp.h
--- ns-2.1b6/packet-stamp.h	Mon Nov 29 23:25:12 1999
+++ proactive-ns-2.1b6/packet-stamp.h	Thu Oct  2 22:58:30 2003
@@ -54,6 +54,7 @@
      objects in the future. */
   double RxPr;			// power with which pkt is received
   double CPThresh;		// capture threshold for recving interface
+  double RXThresh;
 
 protected:
   Antenna       *ant;
diff -u -b -N ns-2.1b6/packet.h proactive-ns-2.1b6/packet.h
--- ns-2.1b6/packet.h	Mon Nov 29 23:25:12 1999
+++ proactive-ns-2.1b6/packet.h	Fri Oct  3 01:06:18 2003
@@ -383,6 +383,9 @@
         int opt_num_forwards_;   // optimal #forwards
 	// Monarch extn ends;
 
+	double warning_thresh_;
+	int hacked_;
+
 	static int offset_;	// offset for this header
 	inline static int& offset() { return offset_; }
 	inline static hdr_cmn* access(Packet* p) {
@@ -404,6 +407,9 @@
 	inline int& num_forwards() { return (num_forwards_); }
 	inline int& opt_num_forwards() { return (opt_num_forwards_); }
         //monarch_end
+
+	inline double& warning_thresh() {return warning_thresh_;}
+	inline int& hacked() {return hacked_;}
 };
 
 
@@ -446,6 +452,10 @@
 	init(p); // Initialize bits_[]
 	(HDR_CMN(p))->next_hop_ = -2; // -1 reserved for IP_BROADCAST
 	(HDR_CMN(p))->last_hop_ = -2; // -1 reserved for IP_BROADCAST
+
+	(HDR_CMN(p))->warning_thresh_=0.0;
+	(HDR_CMN(p))->hacked()=0;
+
 	p->fflag_ = TRUE;
 	(HDR_CMN(p))->direction() = hdr_cmn::DOWN;
 	/* setting all direction of pkts to be downward as default; 
diff -u -b -N ns-2.1b6/rttable.cc proactive-ns-2.1b6/rttable.cc
--- ns-2.1b6/rttable.cc	Mon Nov 29 23:25:18 1999
+++ proactive-ns-2.1b6/rttable.cc	Fri Oct  3 00:31:31 2003
@@ -60,6 +60,7 @@
         rt_expire = 0.0;
         rt_hops = INFINITY2;
         rt_flags = RTF_DOWN;
+	rt_warn = 0;
 
         rt_errors = 0;
         rt_error_time = 0.0;
diff -u -b -N ns-2.1b6/rttable.h proactive-ns-2.1b6/rttable.h
--- ns-2.1b6/rttable.h	Wed Dec 22 18:31:47 1999
+++ proactive-ns-2.1b6/rttable.h	Fri Oct  3 00:31:31 2003
@@ -103,6 +103,8 @@
 #define RTF_UP 1
 #define RTF_IN_REPAIR 2
 
+	u_int8_t        rt_warn;
+
         /*
          *  Must receive 4 errors within 3 seconds in order to mark
          *  the route down.
