$Id: ns-233-mobiwan-1.patch 192 2008-05-06 05:59:58Z omehani $
MobiWan for NS-2.33.  Adaptation of the NS-2.32 patch [0] (based on [1]).
Olivier Mehani <olivier.mehani@nicta.com.au>.

[0] http://mobqos.ee.unsw.edu.au/~omehani/ns/ns-232-mobiwan-103.patch
[1] http://www.arcst.whu.edu.cn/center/kongrs/ns-228-mobiwan-102.diff.gz
====
diff -urNU5 ns-2.33/classifier/classifier-hash.h ns-2.33-mobiwan/classifier/classifier-hash.h
--- ns-2.33/classifier/classifier-hash.h	2008-04-01 13:00:24.000000000 +1100
+++ ns-2.33-mobiwan/classifier/classifier-hash.h	2008-05-06 14:40:09.000000000 +1000
@@ -32,12 +32,16 @@
  * SUCH DAMAGE.
  *
  * $Header: /cvsroot/nsnam/ns-2/classifier/classifier-hash.h,v 1.9 2005/09/18 23:33:31 tomh Exp $
  */
 
+#ifndef ns_classifier_hash_h
+#define ns_classifier_hash_h
+
 #include "classifier.h"
 #include "ip.h"
+#include "connector.h"
 
 class Flow;
 
 /* class defs for HashClassifier (base), SrcDest, SrcDestFid HashClassifiers */
 class HashClassifier : public Classifier {
@@ -179,5 +183,6 @@
 		long key = mshift(dst);
 		return (const char*) key;
 	}
 };
 
+#endif
diff -urNU5 ns-2.33/classifier/classifier-mcast.cc ns-2.33-mobiwan/classifier/classifier-mcast.cc
--- ns-2.33/classifier/classifier-mcast.cc	2008-04-01 13:00:24.000000000 +1100
+++ ns-2.33-mobiwan/classifier/classifier-mcast.cc	2008-05-06 14:40:09.000000000 +1000
@@ -35,10 +35,11 @@
 #ifndef lint
 static const char rcsid[] =
     "@(#) $Header: /cvsroot/nsnam/ns-2/classifier/classifier-mcast.cc,v 1.32 2005/09/26 07:38:08 lacage Exp $";
 #endif
 
+#include <address.h>
 #include <stdlib.h>
 #include "config.h"
 #include "packet.h"
 #include "ip.h"
 #include "classifier.h"
@@ -110,10 +111,28 @@
   		       break;
   	}
 	return (p);
 }
 
+long MCastClassifier::get_id(nsaddr_t src)
+// XXX because src does not correspond to Node id. 
+{
+	Tcl& tcl = Tcl::instance();
+	tcl.evalf("[Simulator instance] get-node-id-by-addr %s", 
+		Address::instance().print_nodeaddr(src));
+	return(atoi(tcl.result()));
+}
+
+nsaddr_t MCastClassifier::get_addr(long src)
+// Return address in binary form corresponding to Node id
+// XXX because src does not correspond to Node id. 
+{
+	Tcl& tcl = Tcl::instance();
+	tcl.evalf("[[Simulator instance] get-node-by-id %ld] set address_",src); 
+	return(Address::instance().str2addr(tcl.result()));
+}
+
 int MCastClassifier::classify(Packet *pkt)
 {
 	hdr_cmn* h = hdr_cmn::access(pkt);
 	hdr_ip* ih = hdr_ip::access(pkt);
 
@@ -132,11 +151,12 @@
 		if ((p = lookup(src, dst)) == 0)
 			p = lookup_star(dst);
 		if (p == 0) {
   			// Didn't find an entry.
 			tcl.evalf("%s new-group %d %d %d cache-miss", 
-				  name(), src, dst, iface);
+				  name(), get_id(src), dst, iface);
+			
 			// XXX see McastProto.tcl for the return values 0 -
 			// once, 1 - twice 
 			//printf("cache-miss result= %s\n", tcl.result());
 			int res= atoi(tcl.result());
 
@@ -144,11 +164,11 @@
 		}
 		if (p->iif == ANY_IFACE.value()) // || iface == UNKN_IFACE.value())
 			return p->slot;
 
 		tcl.evalf("%s new-group %d %d %d wrong-iif", 
-			  name(), src, dst, iface);
+ 			  name(), get_id(src), dst, iface);
 		//printf("wrong-iif result= %s\n", tcl.result());
 		int res= atoi(tcl.result());
 		return (res)? Classifier::TWICE : Classifier::ONCE;
 	}
 	return p->slot;
@@ -183,11 +203,12 @@
 			// $classifier set-hash $src $group $slot $iif
 			//      $iif can be:(1) <number>
 			//                  (2) "*" - matches any interface
 			//                  (3) "?" - interface is unknown (usually this means that
 			//			       the packet came from a local agent)
-			nsaddr_t src = strtol(argv[2], (char**)0, 0);
+			// XXX becauce Node id doesn't correspond to nsaddr
+			nsaddr_t src = get_addr(strtol(argv[2], (char**)0, 0));
 			nsaddr_t dst = strtol(argv[3], (char**)0, 0);
 			int slot = atoi(argv[4]);
                         int iface = (strcmp(argv[5], ANY_IFACE.name())==0) ? ANY_IFACE.value() 
 				: (strcmp(argv[5], UNKN_IFACE.name())==0) ? UNKN_IFACE.value() 
 				: atoi(argv[5]); 
@@ -200,11 +221,12 @@
 			}
 			return (TCL_OK);
 		}
 		if (strcmp(argv[1], "change-iface") == 0) {
 			// $classifier change-iface $src $dst $olfiif $newiif
-			nsaddr_t src = strtol(argv[2], (char**)0, 0);
+			// XXX becauce Node id doesn't correspond to nsaddr
+			nsaddr_t src = get_addr(strtol(argv[2], (char**)0, 0));
 			nsaddr_t dst = strtol(argv[3], (char**)0, 0);
 			int oldiface = atoi(argv[4]);
 			int newiface = atoi(argv[5]);
 			if (strcmp(STARSYM, argv[2]) == 0) {
 				change_iface(dst, oldiface, newiface);
@@ -215,12 +237,13 @@
 		}
 	} else if (argc == 5) {
 		if (strcmp(argv[1], "lookup") == 0) {
 			// $classifier lookup $src $group $iface
 			// returns name of the object (replicator)
+			// XXX becauce Node id doesn't correspond to nsaddr
 			Tcl &tcl = Tcl::instance();
-			nsaddr_t src = strtol(argv[2], (char**)0, 0);
+			nsaddr_t src = get_addr(strtol(argv[2], (char**)0, 0));
 			nsaddr_t dst = strtol(argv[3], (char**)0, 0);
 			int iface = atoi(argv[4]);
 			
 			hashnode* p= (strcmp(STARSYM, argv[2]) == 0) ? lookup_star(dst, iface)
 				: lookup(src, dst, iface);
@@ -232,12 +255,13 @@
 		}
 	} else if (argc == 4) {
 		if (strcmp(argv[1], "lookup-iface") == 0) {
 			// $classifier lookup-iface $src $group 
 			// returns incoming iface
+			// XXX becauce Node id doesn't correspond to nsaddr
 			Tcl &tcl = Tcl::instance();
-			nsaddr_t src = strtol(argv[2], (char**)0, 0);
+			nsaddr_t src = get_addr(strtol(argv[2], (char**)0, 0));
 			nsaddr_t dst = strtol(argv[3], (char**)0, 0);
 			hashnode* p= (strcmp(argv[2], STARSYM) == 0) ? lookup_star(dst)
 				: lookup(src, dst);
 			if (p == 0)
 				tcl.resultf("");
diff -urNU5 ns-2.33/classifier/classifier-mcast.h ns-2.33-mobiwan/classifier/classifier-mcast.h
--- ns-2.33/classifier/classifier-mcast.h	2008-04-01 13:00:24.000000000 +1100
+++ ns-2.33-mobiwan/classifier/classifier-mcast.h	2008-05-06 14:40:09.000000000 +1000
@@ -58,10 +58,12 @@
 	MCastClassifier();
 	~MCastClassifier();
 	static const char STARSYM[]; //"source" field for shared trees
 protected:
 	virtual int command(int argc, const char*const* argv);
+	long get_id(nsaddr_t src);
+	nsaddr_t get_addr(long id);
 	virtual int classify(Packet *p);
 	int findslot();
 	enum {HASHSIZE = 256};
 	struct hashnode {
 		int slot;
diff -urNU5 ns-2.33/common/mobilenode.cc ns-2.33-mobiwan/common/mobilenode.cc
--- ns-2.33/common/mobilenode.cc	2008-04-01 13:00:25.000000000 +1100
+++ ns-2.33-mobiwan/common/mobilenode.cc	2008-05-06 14:40:09.000000000 +1000
@@ -158,10 +158,19 @@
                                 address_, __PRETTY_FUNCTION__);
 #endif
 		        update_position();
 		        log_movement();
 			return TCL_OK;
+		} else if (strcmp(argv[1], "get-bs") == 0) {
+			// begin Mobile IPv6 enhancements
+			Tcl& tcl = Tcl::instance();
+			// We need to know what is the BS, whether -1 or not
+			// if (base_stn_ == -1 ) 
+			// return TCL_ERROR;
+                       	tcl.resultf("%s",Address::instance().print_nodeaddr(base_stn_));  
+			return TCL_OK;
+			// end Mobile IPv6 enhancements
 		} else if(strcmp(argv[1], "log-energy") == 0) {
 			log_energy(1);
 			return TCL_OK;
 		} else if(strcmp(argv[1], "powersaving") == 0) {
 			energy_model()->powersavingflag() = 1;
@@ -263,11 +272,26 @@
 		} else if (strcmp(argv[1],"base-station") == 0) {
 			base_stn_ = atoi(argv[2]);
 			if(base_stn_ == -1)
 				return TCL_ERROR;
 			return TCL_OK;
+		} else if (strcmp(argv[1], "addr") == 0) {
+			// begin IPv6 enhancements
+			// by default, careof address = node->address
+			// This means the node is at home
+			address_ = Address::instance().str2addr(argv[2]);
+			coa_ = address_;
+			return TCL_OK;
 		} 
+		//      else if (strcmp(argv[1],"set-careofaddr") == 0) {
+		//             coa_ = Address::instance().str2addr(argv[2]);
+		//            if(coa_ == -1)
+		//                   return TCL_ERROR;
+		//          return TCL_OK;
+		// } 
+		// end IPv6 enhancements
+
 	} else if (argc == 4) {
 		if (strcmp(argv[1], "idleenergy") == 0) {
 			idle_energy_patch(atof(argv[2]),atof(argv[3]));
 			return TCL_OK;
 		}
diff -urNU5 ns-2.33/common/mobilenode.h ns-2.33-mobiwan/common/mobilenode.h
--- ns-2.33/common/mobilenode.h	2008-04-01 13:00:25.000000000 +1100
+++ ns-2.33-mobiwan/common/mobilenode.h	2008-05-06 14:40:09.000000000 +1000
@@ -136,10 +136,18 @@
 	}
 	inline MobileNode* nextnode() { return link_.le_next; }
 	inline int base_stn() { return base_stn_;}
 	inline void set_base_stn(int addr) { base_stn_ = addr; }
 
+
+	// begin IPv6 
+        // For IPv6, careof address is a co-located address.
+        // ARP needs to know current careof address
+        inline int coa() { return coa_;}
+        inline void set_coa(int addr) {coa_ = addr;}
+	// end IPv6
+
 	void dump(void);
 
 	inline MobileNode*& next() { return next_; }
 	inline double X() { return X_; }
 	inline double Y() { return Y_; }
@@ -235,10 +243,15 @@
         /* 
 	 * base_stn for mobilenodes communicating with wired nodes
          */
 	int base_stn_;
 
+	// begin IPv6 
+        // For IPv6, careof address is a co-located address.
+        // ARP needs to know current careof address
+        int coa_;
+	// end IPv6
 
 	//int last_rt_time_;
 };
 
 #endif // ns_mobilenode_h
diff -urNU5 ns-2.33/common/packet.h ns-2.33-mobiwan/common/packet.h
--- ns-2.33/common/packet.h	2008-04-01 13:00:25.000000000 +1100
+++ ns-2.33-mobiwan/common/packet.h	2008-05-06 14:48:31.000000000 +1000
@@ -177,12 +177,23 @@
 static const packet_t PT_HDLC = 59;
 
         // Bell Labs Traffic Trace Type (PackMime OL)
 static const packet_t PT_BLTRACE = 60;
 
+ 	//MobiWan packets
+static const packet_t PT_PING_ECHO = 61;
+static const packet_t PT_RADS = 62;
+static const packet_t PT_SOL = 63;
+static const packet_t PT_BU = 64;
+static const packet_t PT_BU_HA = 65;
+static const packet_t PT_BU_CN = 66;
+static const packet_t PT_BU_BS = 67;
+static const packet_t PT_BACK = 68;
+static const packet_t PT_BREQ = 69;
+
         // insert new packet types here
-static packet_t       PT_NTYPE = 61; // This MUST be the LAST one
+static packet_t       PT_NTYPE = 70; // This MUST be the LAST one
 
 enum packetClass
 {
 	UNCLASSIFIED,
 	ROUTING,
@@ -371,10 +382,20 @@
 		// HDLC
 		name_[PT_HDLC]="HDLC";
 
 		// XCP
 		name_[PT_XCP]="xcp";
+		//MobiWan packets
+		name_[PT_PING_ECHO]="ping_echo";
+		name_[PT_RADS]="ipv6_rads";
+		name_[PT_SOL]="ipv6_sol";
+		name_[PT_BU]="mipv6_bu";
+		name_[PT_BU_HA]="mipv6_bu_ha";
+		name_[PT_BU_CN]="mipv6_bu_cn";
+		name_[PT_BU_BS]="mipv6_bu_bs";
+		name_[PT_BACK]="mipv6_back";
+		name_[PT_BREQ]="mipv6_breq";
 
 		// Bell Labs (PackMime OL)
 		name_[PT_BLTRACE]="BellLabsTrace";
 		
 		name_[PT_NTYPE]= "undefined";
diff -urNU5 ns-2.33/mac/arp.cc ns-2.33-mobiwan/mac/arp.cc
--- ns-2.33/mac/arp.cc	2008-04-01 13:00:23.000000000 +1100
+++ ns-2.33-mobiwan/mac/arp.cc	2008-05-06 14:40:09.000000000 +1000
@@ -307,11 +307,11 @@
                         exit(1);
                 }
 	}
 
 	if(ah->arp_op == ARPOP_REQUEST &&
-		ah->arp_tpa == node_->address()) {
+		(ah->arp_tpa == node_->address() || ah->arp_tpa == node_->coa())) {
 		
 		hdr_cmn *ch = HDR_CMN(p);
 		char	*mh = (char*)HDR_MAC(p);
 		hdr_ll  *lh = HDR_LL(p);
 
diff -urNU5 ns-2.33/mac/channel.cc ns-2.33-mobiwan/mac/channel.cc
--- ns-2.33/mac/channel.cc	2008-04-01 13:00:23.000000000 +1100
+++ ns-2.33-mobiwan/mac/channel.cc	2008-05-06 14:40:09.000000000 +1000
@@ -119,11 +119,18 @@
 		else if(strcmp(argv[1], "addif") == 0) {
 			((Phy*) obj)->insertchnl(&ifhead_);
 			((Phy*) obj)->setchnl(this);
 			return TCL_OK;
 		}
-
+		else if (strcmp(argv[1], "changeif") == 0) {
+			// For global mobility (one distinct channel per site
+			// Remove netif from previous channel and add it to new channel
+			((Phy*) obj)->removechnl();
+			((Phy*) obj)->insertchnl(&ifhead_);
+                        ((Phy*) obj)->setchnl(this);
+                        return TCL_OK;
+		}
 		// add interface for grid_keeper_
 		/*else if(strncasecmp(argv[1], "grid_keeper", 5) == 0) {
 			grid_keeper_ = (GridKeeper*)obj;
 			return TCL_OK;
 			}*/
diff -urNU5 ns-2.33/mac/phy.cc ns-2.33-mobiwan/mac/phy.cc
--- ns-2.33/mac/phy.cc	2008-04-01 13:00:23.000000000 +1100
+++ ns-2.33-mobiwan/mac/phy.cc	2008-05-06 14:40:09.000000000 +1000
@@ -66,10 +66,14 @@
 
 		if(strcmp(argv[1], "id") == 0) {
 			tcl.resultf("%d", index_);
 			return TCL_OK;
 		}
+		if(strcmp(argv[1], "removechan") == 0) {
+			this->removechnl();
+			return TCL_OK;
+		}
 	}
 
 	else if(argc == 3) {
 
 		TclObject *obj;
diff -urNU5 ns-2.33/Makefile.in ns-2.33-mobiwan/Makefile.in
--- ns-2.33/Makefile.in	2008-04-01 13:00:08.000000000 +1100
+++ ns-2.33-mobiwan/Makefile.in	2008-05-06 14:58:50.000000000 +1000
@@ -66,10 +66,11 @@
 	-I. \
 	@V_INCLUDES@ \
 	-I./tcp -I./sctp -I./common -I./link -I./queue \
 	-I./adc -I./apps -I./mac -I./mobile -I./trace \
 	-I./routing -I./tools -I./classifier -I./mcast \
+	-I./mobiwan \
 	-I./diffusion3/lib/main -I./diffusion3/lib \
 	-I./diffusion3/lib/nr -I./diffusion3/ns \
 	-I./diffusion3/filter_core -I./asim/ -I./qs \
 	-I./diffserv -I./satellite \
 	-I./wpan
@@ -305,10 +306,11 @@
 	pushback/rate-limit.o pushback/rate-limit-strategy.o \
 	pushback/ident-tree.o pushback/agg-spec.o \
 	pushback/logging-data-struct.o \
 	pushback/rate-estimator.o \
 	pushback/pushback-queue.o pushback/pushback.o \
+	mobiwan/ipv6.o mobiwan/mipv6.o \
 	common/parentnode.o trace/basetrace.o \
 	common/simulator.o asim/asim.o \
 	common/scheduler-map.o common/splay-scheduler.o \
 	linkstate/ls.o linkstate/rtProtoLS.o \
 	pgm/classifier-pgm.o pgm/pgm-agent.o pgm/pgm-sender.o \
@@ -482,10 +484,19 @@
         tcl/ctr-mcast/CtrRPComp.tcl \
 	tcl/rlm/rlm.tcl \
 	tcl/rlm/rlm-ns.tcl \
 	tcl/session/session.tcl \
 	tcl/lib/ns-route.tcl \
+	tcl/lib/ns-ping.tcl \
+	tcl/lib/ns-mcast.tcl \
+	tcl/lib/ns-mipv6.tcl \
+	tcl/lib/proc-tools.tcl \
+	tcl/lib/proc-topo.tcl \
+	tcl/lib/ns-topoman.tcl \
+	tcl/lib/proc-mipv6-config.tcl \
+	tcl/lib/proc-mobi-global.tcl \
+	tcl/lib/proc-mobi-config.tcl \
 	tcl/emulate/ns-emulate.tcl \
 	tcl/lan/vlan.tcl \
 	tcl/lan/abslan.tcl \
 	tcl/lan/ns-ll.tcl \
 	tcl/lan/ns-mac.tcl \
diff -urNU5 ns-2.33/mobile/mip.cc ns-2.33-mobiwan/mobile/mip.cc
--- ns-2.33/mobile/mip.cc	2008-04-01 13:00:24.000000000 +1100
+++ ns-2.33-mobiwan/mobile/mip.cc	2008-05-06 14:40:09.000000000 +1000
@@ -31,19 +31,19 @@
 // #ident "@(#)mip.cc  1.4     98/08/21 SMI"
 
 #include <address.h>
 #include "mip.h"
 
-
-#define IP_HEADER_SIZE	20
+//#define IP_HEADER_SIZE	20  
+#include "../mobiwan/ipv6.h"
 
 int hdr_ipinip::offset_;
 static class IPinIPHeaderClass : public PacketHeaderClass {
 public:
         IPinIPHeaderClass() : PacketHeaderClass("PacketHeader/IPinIP",
 					    sizeof(hdr_ipinip*)) {
-		bind_offset(&hdr_ipinip::offset_);
+//		bind_offset(&hdr_ipinip::offset_);
 	}
 } class_ipiniphdr;
 
 static class MIPEncapsulatorClass : public TclClass {
 public:
@@ -98,10 +98,11 @@
 	hdr->sport() = here_.port_;
 	//hdr->dst() = addr_ & ~(~(nsaddr_t)0 << shift_) | (te & mask_) << shift_;;
 	hdr->daddr() = te;
 	hdr->dport() = 1;
 	hdr->ttl() = defttl_;
+	//((hdr_cmn*)p->access(off_cmn_))->size() += IP_HEADER_SIZE;
 	hdr_cmn::access(p)->size() += IP_HEADER_SIZE;
 
 	target_->recv(p,h);
 }
 
@@ -113,17 +114,31 @@
 	}
 } class_mipdecapsulator;
 
 MIPDecapsulator::MIPDecapsulator() : AddressClassifier()
 {
+  //def_target_ = NULL;
 }
 
+
+// int MIPDecapsulator::command(int argc, const char*const* argv)
+// {
+//   if (argc == 3) {
+//     if (strcmp(argv[1], "def-target") == 0) {
+//       def_target_ = (NsObject *)TclObject::lookup(argv[2]);
+//       return TCL_OK;
+//     }
+//   }
+//   return (AddressClassifier::command(argc, argv));
+// }
+
+
 void MIPDecapsulator::recv(Packet* p, Handler *h)
 {
 	hdr_ipinip **ppinhdr = (hdr_ipinip **)hdr_ipinip::access(p);
 	// restore inner header
-	hdr_ip *pouthdr = hdr_ip::access(p);
+	hdr_ip *pouthdr = (hdr_ip *)hdr_ip::access(p);
 	assert(ppinhdr);
 	hdr_ip *pinhdr = &(*ppinhdr)->hdr_;
 	*ppinhdr = (*ppinhdr)->next_;
 	*pouthdr = *pinhdr;
 
@@ -149,10 +164,11 @@
 		Packet::free(p);
 		return;
 	}
 	delete pinhdr;
 
+ 	//((hdr_cmn*)p->access(off_cmn_))->size() -= IP_HEADER_SIZE;
 	hdr_cmn::access(p)->size() -= IP_HEADER_SIZE;
 
 	link->recv(p,h);
 }
 
diff -urNU5 ns-2.33/mobile/mip.h ns-2.33-mobiwan/mobile/mip.h
--- ns-2.33/mobile/mip.h	2008-04-01 13:00:24.000000000 +1100
+++ ns-2.33-mobiwan/mobile/mip.h	2008-05-06 14:40:09.000000000 +1000
@@ -95,11 +95,11 @@
 	struct hdr_ipinip *next_;	// XXX multiple encapsulation OK
 
 	// Header access methods
 	static int offset_; // required by PacketHeaderManager
 	inline static int& offset() { return offset_; }
-	inline static hdr_ipinip* access(const Packet* p) {
+	inline static hdr_ipinip* access(Packet* p) {
 		return (hdr_ipinip*) p->access(offset_);
 	}
 };
 
 typedef enum {
@@ -128,17 +128,26 @@
 	void recv(Packet *p, Handler *h);
 protected:
 	ns_addr_t here_;
 	int mask_;
 	int shift_;
+ 	int off_ip_;
+ 	int off_ipinip_;
 	int defttl_;
 };
 
 class MIPDecapsulator : public AddressClassifier {
 public:
 	MIPDecapsulator();
 	void recv(Packet* p, Handler* h);
+protected:
+	//int command(int argc, const char*const*argv);
+	int off_ipinip_;		/* XXX to be removed */
+	int off_ip_;
+	/* the default target for decapsulator in mobilenodes 
+	   shall be the node entry point */
+	//NsObject *def_target_;
 };
 
 class SimpleTimer : public TimerHandler {
 public: 
 	SimpleTimer(Agent *a) : TimerHandler() { a_ = a; }
@@ -164,10 +173,11 @@
 	int shift_;
 #ifndef notdef
 	int seqno_;		/* current ad seqno */
 #endif
 	double adlftm_;	/* ads lifetime */
+ 	int off_mip_;
 };
 
 class MIPMHAgent;
 
 class AgtListTimer : public TimerHandler {
@@ -208,10 +218,11 @@
 #ifndef notdef
 	int seqno_;		/* current registration seqno */
 #endif
 	double reglftm_;	/* registration lifetime */
 	double adlftm_;		/* current ads lifetime */
+ 	int off_mip_;
 	MobileNode *node_;      /* ptr to my mobilenode,if appl. */
 
 };
 
 #endif
diff -urNU5 ns-2.33/mobiwan/classifier-src.h ns-2.33-mobiwan/mobiwan/classifier-src.h
--- ns-2.33/mobiwan/classifier-src.h	1970-01-01 10:00:00.000000000 +1000
+++ ns-2.33-mobiwan/mobiwan/classifier-src.h	2008-05-06 14:40:09.000000000 +1000
@@ -0,0 +1,44 @@
+/* This software comprises contributed code made by Motorola, as a 
+ * Contributor, to Network Simulator NS-2 software provided by the 
+ * Regents of the University of California.
+ * (Copyright; Regents of the University of California, 1994)
+ * The contributed code was made as a result of a partnership between 
+ * Motorola and INRIA Rhone-Alpes. 
+ *
+ * Copyright in the contributed code belongs to Motorola Inc. 2001
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ALL ADVERTISING MATERIALS MENTIONING FEATURES OR USE OF THIS SOFTWARE MUST 
+ * DISPLAY AN ACKNOWLEDGEMENT TO THE COPYRIGHT OWNERS. 
+ * ANY REDISTRIBUTION OF THIS SOFTWARE MUST CONTAIN THE ABOVE COPYRIGHT NOTICES, 
+ * CONDITIONS AND DISCLAIMER.
+ */
+
+/* ############################################################################
+ * This code was developed by Thierry Ernst (1998-2001)
+ * MOTOROLA Labs Paris FRANCE - INRIA Rhone-Alpes Grenoble (PLANETE) FRANCE 
+ * NS-2.1b6 enhancements for Wide-Area mobility simulations
+ * ############################################################################
+ */
+
+class SrcHashClassifier : public HashClassifier {
+public:
+        SrcHashClassifier() : HashClassifier(TCL_ONE_WORD_KEYS) {}
+        int command(int argc, const char*const* argv);
+        int classify(Packet *p);
+protected:
+        const char* hashkey(nsaddr_t src, nsaddr_t, int) {
+                return (const char*) mshift(src);
+        }
+};
+
diff -urNU5 ns-2.33/mobiwan/ipv6.cc ns-2.33-mobiwan/mobiwan/ipv6.cc
--- ns-2.33/mobiwan/ipv6.cc	1970-01-01 10:00:00.000000000 +1000
+++ ns-2.33-mobiwan/mobiwan/ipv6.cc	2008-05-06 14:40:09.000000000 +1000
@@ -0,0 +1,528 @@
+
+/* This software comprises contributed code made by Motorola, as a 
+ * Contributor, to Network Simulator NS-2 software provided by the 
+ * Regents of the University of California.
+ * (Copyright; Regents of the University of California, 1994)
+ * The contributed code was made as a result of a partnership between 
+ * Motorola and INRIA Rhone-Alpes. 
+ *
+ * Copyright in the contributed code belongs to Motorola Inc. 2001
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ALL ADVERTISING MATERIALS MENTIONING FEATURES OR USE OF THIS SOFTWARE MUST 
+ * DISPLAY AN ACKNOWLEDGEMENT TO THE COPYRIGHT OWNERS. 
+ * ANY REDISTRIBUTION OF THIS SOFTWARE MUST CONTAIN THE ABOVE COPYRIGHT NOTICES, 
+ * CONDITIONS AND DISCLAIMER.
+ */
+
+/* ############################################################################
+ * This code was developed by Thierry Ernst (1998-2001)
+ * MOTOROLA Labs Paris FRANCE - INRIA Rhone-Alpes Grenoble (PLANETE) FRANCE 
+ * NS-2.1b6 enhancements for Wide-Area mobility simulations
+ * ############################################################################
+ */
+
+// *************************************************************************
+//                              ipv6.cc  
+//      IPv6 Extensions  
+//
+// **************************************************************************
+#include <iostream>
+#include <address.h>
+#include <node.h>
+#include "agent.h"
+//#include "classifier.h"
+#include "classifier-hash.h"
+#include "classifier-src.h"
+#include "ipv6.h"
+#include "ipv6-routing.h"
+
+// Check if I need the following include
+extern "C" {
+#include <stdarg.h>
+};
+
+#include <cmu-trace.h>
+#include <mobilenode.h>
+#include "packet.h"
+
+#define PRINTADDR(a)     Address::instance().print_nodeaddr(a)
+
+// **************************************************************
+// Router Advertisement for Mobile IPv6 Base Stations
+// **************************************************************
+int hdr_rtads::offset_;
+static class RTADSHeaderClass : public PacketHeaderClass {
+public:
+        RTADSHeaderClass() : PacketHeaderClass("PacketHeader/RTADS",
+                                             sizeof(hdr_rtads)) {
+            bind_offset(&hdr_rtads::offset_);
+        }
+} class_rtadshdr;
+
+// **************************************************************
+// Source Routing Extensions for Mobility Support in IPv6
+// **************************************************************
+
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Source Routing Extensions.
+// New Packet header to contain a list of IP addresses where the
+// packet must transit
+// Routing Header should only be inserted by the source node
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+int hdr_rtext::offset_;
+static class RtExtHeaderClass : public PacketHeaderClass {
+public:
+        RtExtHeaderClass() : PacketHeaderClass("PacketHeader/Routing",
+					    sizeof(hdr_rtext)) {
+		bind_offset(&hdr_rtext::offset_);
+	}
+} class_rtexthdr;
+
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Source Routing Extensions.
+// This class inserts a routing header in the packets
+// The Routing Header contains a list of nodes where the packet
+// must transit prior to reaching its final destination.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+static class SrcRoutingClass : public TclClass {
+public:
+        SrcRoutingClass() : TclClass("SrcRouting") {}
+        TclObject* create(int, const char*const*) {
+                return (new SrcRouting());
+        }
+} class_srcrouting;
+
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Source Routing class definition 
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+SrcRouting::SrcRouting() : Connector(), node_(0) 
+{
+       bind("port_", &port_);
+}
+
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// If local node is the source of the packet, we have to insert
+// the routing header - this also means we have an entry in the
+// Binding Cache corresponding to destination.	
+// XXX:  For now, only tested with one address in the routing header.
+// XXX   Should also work with more than one (to be checked) 
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+void SrcRouting::recv(Packet* p, Handler *h)
+{
+   Tcl& tcl = Tcl::instance();
+   hdr_ip* iph = HDR_IP(p);
+   hdr_cmn* cmh = HDR_CMN(p);
+   hdr_rtext* rth = HDR_ROUTING(p);
+
+   if ( iph->saddr() == node_->address() ) {
+
+	// I need to insert an address in the header
+	// Get destination address recorded in Binding Cache:
+	// XXX: should rather access directly to the B Cache,
+	// XXX  instead of calling OTcl.  Change this later. 
+	int daddr = Address::instance().get_nodeaddr(iph->daddr());
+	tcl.evalf("%s lookup-binding-cache %d", name_, daddr);
+	int te = atoi(tcl.result());
+
+	// Add the new transit address in the header
+	ns_hop *hop = new ns_hop;
+	hop->dst_ = iph->dst();
+	hop->next_ = rth->nexthop_;  
+	rth->nexthop_ = hop;
+	rth->nb() ++;
+
+	// Because Routing Header is processed after port_dmux 
+	// for ease of use:
+	iph->daddr() = te;
+	iph->dport() = port_;
+
+	// Size of routing header depends on number of addresses 
+	// recorded in it:
+	cmh->size() += IPv6_RTHDR_SIZE(rth->nb());
+
+   } else {
+	// If packet reaches here, this means this node is the 
+	// destination of the packet as specified in the IP dst field.
+	//  We may check this, but there is no reason to be wrong (...) 
+
+	// I need to switch dst with address contained in header
+	assert ( rth->nb() > 0 ); 
+	rth->nb()--;
+	iph->dst() = rth->nexthop_->dst_;
+	rth->nexthop_ = rth->nexthop_->next_;
+   } 
+   // Pass packet to next object. 
+   target_->recv(p,h);
+}
+
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+int SrcRouting::command(int argc, const char*const* argv)
+{
+   if (argc == 3) {
+      if (strcmp(argv[1], "node") == 0) {
+        node_ = (Node*)TclObject::lookup(argv[2]);
+	if (node_ == 0) {
+           fprintf (stderr, "%s: %s lookup of %s failed\n", __FILE__, argv[1], 
+argv[2]);
+           return TCL_ERROR;
+        }
+        return TCL_OK;
+      }
+   }
+   return (Connector::command(argc, argv));
+}
+ 
+// **************************************************************
+// Classification by source address
+// Adapted from classifier-hash.cc
+// **************************************************************
+static class SrcHashClassifierClass : public TclClass {
+public:
+        SrcHashClassifierClass() : TclClass("Classifier/Hash/Src") {}
+        TclObject* create(int, const char*const*) {
+                return new SrcHashClassifier;
+        }
+
+} class_hash_src_classifier;
+
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+int SrcHashClassifier::classify(Packet *p)
+{
+        int slot= lookup(p);
+        if (slot >= 0 && slot <=maxslot_)
+                return (slot);
+        else if (default_ >= 0)
+                return (default_);
+        return -1;
+} // HashClassifier::classify
+
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+int SrcHashClassifier::command(int argc, const char*const* argv)
+{
+   if (argc == 4) {
+        // $classifier install $src $node
+        if (strcmp(argv[1], "install") == 0) {
+           nsaddr_t src = atoi(argv[2]);
+           NsObject *node = (NsObject*)TclObject::lookup(argv[3]);
+           int slot = getnxt(node);
+           install(slot, node);
+           if (set_hash(src, 0, 0, slot) >= 0)
+               return TCL_OK;
+           else
+               return TCL_ERROR;
+           } // if
+   }
+   return(HashClassifier::command(argc, argv));
+} // command
+
+
+// *************************************************************************
+// >----------------------------------------------------------------------<
+// >                       Network Agent                                  <
+// >----------------------------------------------------------------------<
+// *************************************************************************
+
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+static void 
+mac_callback (Packet * p, void *arg)
+{
+  // ((NetworkAgent *) arg)->lost_link (p);
+}
+
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+void 
+NetworkAgent::sendOutBCastPkt(Packet *p)
+{
+   hdr_cmn *cmh = HDR_CMN(p);
+   cmh->next_hop_ = IP_BROADCAST; 
+   cmh->addr_type_ = NS_AF_INET; 
+   target_->recv(p, (Handler *)0);
+}
+
+NetworkAgent::NetworkAgent (): Agent (PT_MESSAGE), myaddr_(0), node_(0), port_dmux_(0), 
+print_info_(0)
+ 
+{
+  bind ("print_info_", &print_info_);
+}
+
+// *************************************************************************
+int 
+NetworkAgent::command (int argc, const char *const *argv)
+{
+  if (argc == 2)
+    {
+      if (strcmp (argv[1], "start-site") == 0)
+	{
+	  // Nothing for now 
+	  return (TCL_OK);
+	}
+    }
+  else if (argc == 3)
+    {
+      if (strcasecmp (argv[1], "addr") == 0) {
+	 myaddr_ = Address::instance().str2addr(argv[2]);
+	 return TCL_OK;
+      }
+      TclObject *obj;
+      if ((obj = TclObject::lookup (argv[2])) == 0)
+	{
+	  fprintf (stderr, "%s: %s lookup of %s failed\n", __FILE__, argv[1],
+		   argv[2]);
+	  return TCL_ERROR;
+	}
+      if (strcasecmp (argv[1], "tracetarget") == 0)
+	{
+	  // tracetarget = (Trace *) obj;
+	  return TCL_OK;
+	}
+      else if (strcasecmp (argv[1], "node") == 0) {
+	      node_ = (MobileNode*) obj;
+	      return TCL_OK;
+      }
+      else if (strcasecmp (argv[1], "port-dmux") == 0) {
+	      port_dmux_ = (NsObject *) obj;
+	      return TCL_OK;
+      }
+    }
+  
+  return (Agent::command (argc, argv));
+}
+
+// *************************************************************************
+// >----------------------------------------------------------------------<
+// >                    Network BS Agent                                  <
+// >----------------------------------------------------------------------<
+// *************************************************************************
+void
+NetworkBS::recv (Packet * p, Handler *)
+{
+  hdr_ip *iph = HDR_IP(p);
+  hdr_cmn *cmh = HDR_CMN(p);
+  int src = Address::instance().get_nodeaddr(iph->saddr());
+
+  if (src == myaddr_) {
+     // Packet I'm originating
+     if (cmh->num_forwards() != 0) {
+	// I received a packet that I sent.  
+	// Probably  a routing loop.
+	if (print_info_) cout << "\tNetworkBS - Routing Loop - drop\n";
+	drop(p, DROP_RTR_ROUTE_LOOP);
+	return;
+     }
+     else {
+	// set direction of pkt to -1 , i.e downward
+	cmh->direction() = hdr_cmn::DOWN;
+	cmh->prev_hop_ = myaddr_;
+	iph->ttl_ = IP_DEF_TTL;
+		
+        if (iph->daddr() == IP_BROADCAST) {
+	   sendOutBCastPkt(p);
+	}
+	else {
+	   if (print_info_) cout << "\tNetworkBS - HA forwarding to MN\n";
+	   
+	   cmh->addr_type_ = NS_AF_INET;
+	   cmh->xmit_failure_ = mac_callback;
+	   cmh->xmit_failure_data_ = this;
+	   cmh->next_hop_ = Address::instance().get_nodeaddr(iph->daddr());
+	   assert (!HDR_CMN (p)->xmit_failure_ ||
+		HDR_CMN (p)->xmit_failure_ == mac_callback);
+	   target_->recv(p, (Handler *)0);
+	}
+     }	
+  } 
+  else {
+     	// Packet I receive
+   	if (print_info_) {
+		cout << "\tNetworkBS " << PRINTADDR(myaddr_);
+		cout << " from " << PRINTADDR(src);
+  	 }	
+
+	if (--iph->ttl_ == 0) {
+	   // Packet I'm forwarding...   
+	   // Check the TTL.  If it is zero, then discard.
+	   if (print_info_) cout << " - TTL expired - drop\n";
+	   drop(p, DROP_RTR_TTL);
+	   return;
+	} 
+	else  if ((u_int32_t) iph->daddr() == IP_BROADCAST) {
+	   // Broadcast that I receive 
+	   // hand it over to the port-demux
+	   if (print_info_) cout << " - receiving BROADCAST\n";
+	   port_dmux_->recv(p, (Handler*)0);
+	   }
+	else {
+	   // BS forwarding to wireless (Mobile Node)
+	   if (print_info_)
+	     cout << " - forward to MN " << PRINTADDR(iph->daddr()) << "\n";
+	   cmh->direction() = hdr_cmn::DOWN;
+	   cmh->prev_hop_ = myaddr_;
+	   cmh->next_hop_ = Address::instance().get_nodeaddr(iph->daddr());
+	   target_->recv(p, (Handler *)0);
+	}
+  }
+return;
+}
+
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+static class NetworkBSClass:public TclClass
+{
+public:
+  NetworkBSClass ():TclClass ("Agent/Network/NetworkBS") {}
+  TclObject *create (int, const char *const *) {
+    return (new NetworkBS);
+  }
+} class_networkbs;
+
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+NetworkBS::NetworkBS() : NetworkAgent()
+{
+}
+
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+int NetworkBS::command (int argc, const char *const *argv)
+{
+  return (NetworkAgent::command (argc, argv));
+}
+
+// *************************************************************************
+// >----------------------------------------------------------------------<
+// >                    Network MN Agent                                  <
+// >----------------------------------------------------------------------<
+// *************************************************************************
+static class NetworkMNClass:public TclClass
+{
+public:
+  NetworkMNClass ():TclClass ("Agent/Network/NetworkMN") {}
+  TclObject *create (int, const char *const *) {
+    return (new NetworkMN);
+  }
+} class_networkmn;
+
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+NetworkMN::NetworkMN() : NetworkAgent(), mipagent_(0), decap_port_(-1)
+{
+}
+
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+void
+NetworkMN::recv (Packet * p, Handler *)
+{
+  hdr_ip *iph = HDR_IP(p);
+  hdr_cmn *cmh = HDR_CMN(p);
+  int src = Address::instance().get_nodeaddr(iph->saddr());
+
+  if (src == myaddr_) {
+     // Packet I'm originating
+     if (cmh->num_forwards() != 0) {
+        // I received a packet that I sent.  
+        // Probably  a routing loop.
+	if (print_info_) cout << "\tNetworkMN - Routing Loop - drop\n";
+        drop(p, DROP_RTR_ROUTE_LOOP);
+        return;
+     }
+     else {
+        // set direction of pkt to -1 , i.e downward
+        cmh->direction() = hdr_cmn::DOWN;
+        cmh->prev_hop_ = myaddr_;
+        iph->ttl_ = IP_DEF_TTL;
+                
+        if ( iph->daddr() == IP_BROADCAST) {
+           sendOutBCastPkt(p);
+        }
+        else {
+	   // I am a Mobile IPv6 Node
+	   // Forward DTG to my current base station
+	   if (print_info_) 
+		cout << "\tNetworkMN " << PRINTADDR(myaddr_)
+		<< " from " << PRINTADDR(src)
+		<< " forward to BS " << PRINTADDR(node_->base_stn()) << "\n";
+           
+           cmh->addr_type_ = NS_AF_INET;
+           cmh->xmit_failure_ = mac_callback;
+           cmh->xmit_failure_data_ = this;
+	   cmh->next_hop_ = node_->base_stn();
+           assert (!HDR_CMN (p)->xmit_failure_ ||
+                HDR_CMN (p)->xmit_failure_ == mac_callback);
+           target_->recv(p, (Handler *)0);
+        }
+     }  
+  } 
+  else {
+        // Packet I receive
+   	if (print_info_) {
+		cout << "\tNetworkMN " << PRINTADDR(myaddr_)
+		<< " from " << PRINTADDR(src) << " to " 
+		<< PRINTADDR(iph->daddr());
+   	} 
+
+        if (--iph->ttl_ == 0) {
+           // Packet I'm forwarding...   
+           // Check the TTL.  If it is zero, then discard.
+	   if (print_info_) cout << " - TTL expired - drop\n";
+           drop(p, DROP_RTR_TTL);
+           return;
+        } 
+        else  if ((u_int32_t) iph->daddr() == IP_BROADCAST) {
+           // Broadcast that I receive 
+	   // (Likely a Router Advertisement)
+           // hand it over to the port-demux
+	   if (print_info_) cout << " - receiving BROADCAST\n";
+           port_dmux_->recv(p, (Handler*)0);
+           }
+        else {
+	   // DTG for myself
+	   // Probably a packet with destination = COA (with routing header 
+	   // or encapsulation) otherwise may have not reach here 
+	   if (print_info_) cout << " - receiving DTG " << cmh->ptype_ <<"\n";
+
+	   // If it comes encapsulated, we may want to send BU to 
+	   // src addr in the encapsulated header.  We add the 
+	   // source in the Binding List.
+	   // XXX: not very cool: we check inside header before
+	   // packet is effectively decapsulated ... 
+	   if ( iph->dport() == decap_port_ ) {
+	      hdr_ipinip **ppinhdr = (hdr_ipinip **)hdr_ipinip::access(p);
+	      hdr_ip *pinhdr = &(*ppinhdr)->hdr_;
+	      mipagent_->add_bulist(pinhdr->saddr(), BU_CN, ON);
+	   } else {
+	      mipagent_->add_bulist(iph->saddr(), BU_CN, ON);
+	   } 
+	   port_dmux_->recv(p, (Handler*)0);
+        }
+  }
+return;
+}
+
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+int NetworkMN::command (int argc, const char *const *argv)
+{
+  if ( argc == 3 ) {
+     if (strcmp(argv[1], "mip-agent") == 0) {
+        mipagent_ = (MNAgent*)TclObject::lookup(argv[2]); 
+        return TCL_OK;
+     }
+     if (strcmp(argv[1], "decap-port") == 0) {
+        decap_port_ = atoi(argv[2]); 
+        return TCL_OK;
+     }
+  }
+  return (NetworkAgent::command (argc, argv));
+  
+}
+
+
+
+
diff -urNU5 ns-2.33/mobiwan/ipv6.h ns-2.33-mobiwan/mobiwan/ipv6.h
--- ns-2.33/mobiwan/ipv6.h	1970-01-01 10:00:00.000000000 +1000
+++ ns-2.33-mobiwan/mobiwan/ipv6.h	2008-05-06 14:40:09.000000000 +1000
@@ -0,0 +1,154 @@
+/* This software comprises contributed code made by Motorola, as a 
+ * Contributor, to Network Simulator NS-2 software provided by the 
+ * Regents of the University of California.
+ * (Copyright; Regents of the University of California, 1994)
+ * The contributed code was made as a result of a partnership between 
+ * Motorola and INRIA Rhone-Alpes. 
+ *
+ * Copyright in the contributed code belongs to Motorola Inc. 2001
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ALL ADVERTISING MATERIALS MENTIONING FEATURES OR USE OF THIS SOFTWARE MUST 
+ * DISPLAY AN ACKNOWLEDGEMENT TO THE COPYRIGHT OWNERS. 
+ * ANY REDISTRIBUTION OF THIS SOFTWARE MUST CONTAIN THE ABOVE COPYRIGHT NOTICES, 
+ * CONDITIONS AND DISCLAIMER.
+ */
+
+/* ############################################################################
+ * This code was developed by Thierry Ernst (1998-2001)
+ * MOTOROLA Labs Paris FRANCE - INRIA Rhone-Alpes Grenoble (PLANETE) FRANCE 
+ * NS-2.1b6 enhancements for Wide-Area mobility simulations
+ * ############################################################################
+ */
+
+
+// *************************************************************************
+//                              ipv6.h
+//      IPv6 Extensions  
+//
+// **************************************************************************
+
+#ifndef ipv6_h
+#define ipv6_h
+
+#include "mip.h"
+#include "ip.h"
+#include "connector.h"
+#include "mipv6.h"
+
+// Do I need the 3 following ?
+#include "config.h"
+#include "agent.h"
+#include "mac.h"
+
+
+#define IPv6_ADDR_SIZE 		16
+#define IPv6_HEADER_SIZE 	2 * IPv6_ADDR_SIZE + 8 
+#define DEST_HDR_PREFIX_SIZE	2
+#define IP_HEADER_SIZE IPv6_HEADER_SIZE
+#define UDP_HDR_SIZE		8
+
+// **************************************************************************
+// IPv6 Router advertisements and Solicitations
+// RFC2461
+// XXX: Soliciations does not need a specific packet format
+// **************************************************************************
+#define HDR_RTADS(p)    ((struct hdr_rtads*)(p)->access(hdr_rtads::offset_))
+struct hdr_rtads {
+        double lftm_;
+	// I should add the prefix as an option
+
+        static int offset_;
+        inline static int& offset() { return offset_; }
+        inline static hdr_rtads* access(Packet* p) {
+                return (hdr_rtads*) p->access(offset_);
+        }
+        inline double& lifetime() { return lftm_; }
+};
+
+#define PT_RSOL_SIZE		IPv6_HEADER_SIZE + 8
+#define PT_RADS_SIZE		IPv6_HEADER_SIZE + 16
+
+// **************************************************************************
+// IPv6 Routing Header
+// **************************************************************************
+#define ROUTE_HDR_SIZE		16
+#define IPv6_RTHDR_SIZE(n)	16 * n +8 
+
+// Multiple hops OK
+typedef struct ns_hop_list {
+	ns_addr_t       dst_;	
+	struct ns_hop_list *next_;
+} ns_hop;
+	
+#define HDR_ROUTING(p)	((struct hdr_rtext*)(p)->access(hdr_rtext::offset_))
+struct hdr_rtext {
+	ns_hop *nexthop_;    // Next hop, not "next header"	
+	int nb_;
+	static int offset_;
+        inline static int& offset() { return offset_; }
+
+	inline static hdr_rtext* access(Packet* p) {
+                return (hdr_rtext*) p->access(offset_);
+        }
+	inline int& nb() { return nb_ ; }
+};
+
+
+// >----------------------------------------------------------------------<
+// >                          Network Agent                               <
+// >----------------------------------------------------------------------<
+// taken from dsdv agent
+
+class NetworkAgent : public Agent {
+public:
+  NetworkAgent();
+  virtual int command(int argc, const char * const * argv);
+
+protected:
+  void sendOutBCastPkt(Packet *p);
+  int myaddr_;              // My address...
+  MobileNode *node_;        // My node
+  NsObject *port_dmux_;     // my port dmux
+  int print_info_;
+};
+
+// >----------------------------------------------------------------------<
+// >                       Network BS Agent                               <
+// >----------------------------------------------------------------------<
+class NetworkBS : public NetworkAgent {
+public:
+  NetworkBS();
+  virtual int command(int argc, const char * const * argv);
+
+protected:
+  virtual void recv(Packet *, Handler *);
+};
+
+// >----------------------------------------------------------------------<
+// >                       Network MN Agent                               <
+// >----------------------------------------------------------------------<
+class NetworkMN : public NetworkAgent {
+public:
+  NetworkMN();
+  virtual int command(int argc, const char * const * argv);
+
+protected:
+  virtual void recv(Packet *, Handler *);
+  MNAgent *mipagent_;
+  int decap_port_;
+  int off_ipinip_;
+};
+
+#endif
+
diff -urNU5 ns-2.33/mobiwan/ipv6-routing.h ns-2.33-mobiwan/mobiwan/ipv6-routing.h
--- ns-2.33/mobiwan/ipv6-routing.h	1970-01-01 10:00:00.000000000 +1000
+++ ns-2.33-mobiwan/mobiwan/ipv6-routing.h	2008-05-06 14:40:09.000000000 +1000
@@ -0,0 +1,52 @@
+/* This software comprises contributed code made by Motorola, as a 
+ * Contributor, to Network Simulator NS-2 software provided by the 
+ * Regents of the University of California.
+ * (Copyright; Regents of the University of California, 1994)
+ * The contributed code was made as a result of a partnership between 
+ * Motorola and INRIA Rhone-Alpes. 
+ *
+ * Copyright in the contributed code belongs to Motorola Inc. 2001
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ALL ADVERTISING MATERIALS MENTIONING FEATURES OR USE OF THIS SOFTWARE MUST 
+ * DISPLAY AN ACKNOWLEDGEMENT TO THE COPYRIGHT OWNERS. 
+ * ANY REDISTRIBUTION OF THIS SOFTWARE MUST CONTAIN THE ABOVE COPYRIGHT NOTICES, 
+ * CONDITIONS AND DISCLAIMER.
+ */
+
+/* ############################################################################
+ * This code was developed by Thierry Ernst (1998-2001)
+ * MOTOROLA Labs Paris FRANCE - INRIA Rhone-Alpes Grenoble (PLANETE) FRANCE 
+ * NS-2.1b6 enhancements for Wide-Area mobility simulations
+ * ############################################################################
+ */
+
+#include "connector.h"
+
+// Use a connector because this is simpler than an agent (no need for
+// variable TTL etc ...
+class SrcRouting : public Connector { 
+public:
+        SrcRouting();
+        void recv(Packet *p, Handler *h);
+protected:
+	int command(int argc, const char*const*argv);
+	int port_;
+	Node *node_;
+  //   	int mask_;
+  // 	int shift_;
+  //   	int off_ip_;
+  //   	int off_ipinip_;
+};
+
+
diff -urNU5 ns-2.33/mobiwan/mipv6.cc ns-2.33-mobiwan/mobiwan/mipv6.cc
--- ns-2.33/mobiwan/mipv6.cc	1970-01-01 10:00:00.000000000 +1000
+++ ns-2.33-mobiwan/mobiwan/mipv6.cc	2008-05-06 14:40:09.000000000 +1000
@@ -0,0 +1,1085 @@
+/* This software comprises contributed code made by Motorola, as a 
+ * Contributor, to Network Simulator NS-2 software provided by the 
+ * Regents of the University of California.
+ * (Copyright; Regents of the University of California, 1994)
+ * The contributed code was made as a result of a partnership between 
+ * Motorola and INRIA Rhone-Alpes. 
+ *
+ * Copyright in the contributed code belongs to Motorola Inc. 2001
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ALL ADVERTISING MATERIALS MENTIONING FEATURES OR USE OF THIS SOFTWARE MUST 
+ * DISPLAY AN ACKNOWLEDGEMENT TO THE COPYRIGHT OWNERS. 
+ * ANY REDISTRIBUTION OF THIS SOFTWARE MUST CONTAIN THE ABOVE COPYRIGHT NOTICES, 
+ * CONDITIONS AND DISCLAIMER.
+ */
+
+/* ############################################################################
+ * This code was developed by Thierry Ernst (1998-2001)
+ * MOTOROLA Labs Paris FRANCE - INRIA Rhone-Alpes Grenoble (PLANETE) FRANCE 
+ * NS-2.1b6 enhancements for Wide-Area mobility simulations
+ * ############################################################################
+ */
+
+// *************************************************************************
+// 				mipv6.cc  
+//      Mobility Support in IPv6 
+//	Based on <draft-ietf-mobileip-ipv6-11.txt> March 2000 with some
+// 	simplifications.
+//
+// **************************************************************************
+#define MYNUM	Address::instance().print_nodeaddr(addr())
+#define MIPHAD	Address::instance().print_nodeaddr(miph->haddr())
+#define PRINTADDR(a)     Address::instance().print_nodeaddr(a)
+#define GETADDR(a)     Address::instance().get_nodeaddr(a)
+#define HADDR	Address::instance().get_nodeaddr(addr())
+#define MIPv6DEBUG
+
+#include <template.h>
+#include <random.h>
+#include <address.h>
+#include <mobilenode.h>
+#include <assert.h>
+
+#include <iostream>
+#include <list>
+#include "ipv6.h"
+#include "mipv6.h"
+
+// *************************************************************************
+// >----------------------------------------------------------------------<
+// Mobile IPv6 Binding Update Header
+// >----------------------------------------------------------------------<
+// *************************************************************************
+int hdr_mipv6::offset_;
+static class MIPv6HeaderClass : public PacketHeaderClass {
+public:
+	MIPv6HeaderClass() : PacketHeaderClass("PacketHeader/MIPv6",
+					     sizeof(hdr_mipv6)) {
+	    bind_offset(&hdr_mipv6::offset_);
+        }
+        void export_offsets() {
+                field_offset("coa_", OFFSET(hdr_mipv6, coa()));
+        }
+} class_mipv6hdr;
+
+// *************************************************************************
+// >----------------------------------------------------------------------<
+// MIPv6 Base Agent
+// >----------------------------------------------------------------------<
+// *************************************************************************
+static class MIPv6AgentClass : public TclClass {
+public:
+        MIPv6AgentClass() : TclClass("Agent/MIPv6") {}
+        TclObject* create(int, const char*const*) {
+                return (new MIPv6Agent());
+        }
+} class_mipv6agent;
+
+
+MIPv6Agent::MIPv6Agent() : Agent(PT_UDP), bcast_target_(0), timer_(this),
+beacon_(1.0), print_info_(0)
+{
+	// Binding Cache - mostly to collect statistics
+        LIST_INIT(&bcache_head_);
+        
+	bind("print_info_", &print_info_);
+}
+
+// *************************************************************************
+// Recipient may altrenatively be a Base Station, a Home Agent, or a 
+// simple Correspondent Node
+// *************************************************************************
+void MIPv6Agent::recv(Packet* p, Handler *)
+{
+   hdr_mipv6 *miph = HDR_MIPv6(p);
+   hdr_cmn *hdrc = HDR_CMN(p);
+   //printf("MIPv^AGENT:recv at %s\n", name());
+   switch (hdrc->ptype()) {
+      case PT_BU:
+          if (miph->H() == ON) {
+	     // Home Registration
+	     // XXX: No distinction in the simulation
+	     strcpy( node_info_, "HA");
+	     mn_registration(p);
+	  } else
+	     mn_registration(p);
+	  break;
+
+      case PT_SOL:
+	  // Process Solicitations from MN
+	  send_ads();
+	  timer_.resched(Random::uniform(0, beacon_));
+	  //timer_.resched(beacon_);
+	  break;
+
+      case PT_RADS:
+ 	  // Advertisement from other BSs.  Just ignore
+	  break;
+
+      default:
+	  fprintf(stderr, "%s received packet with wrong type\n", node_info_);
+	  // exit(1); 
+	  break;
+	}
+   Packet::free(p);
+}
+
+// *************************************************************************
+// Send the Mobile IPv6 Packet  
+// *************************************************************************
+void MIPv6Agent::send_packet(Packet *p)
+{
+   hdr_cmn *hdrc = HDR_CMN(p);
+   hdr_mipv6 *miph = HDR_MIPv6(p);
+   hdr_ip *iph = HDR_IP(p);
+
+   if (print_info_) {
+      switch (hdrc->ptype()) {
+	case PT_BACK:
+	   cout << "+ " << node_info_ << " " << MYNUM << " send ACK [" 
+	   << miph->seqno() << "] to " << PRINTADDR(iph->daddr()) << "\n";
+	   break;
+
+	case PT_BU:
+	    cout << "+ " << node_info_ << " " << MYNUM << " send BU [" 
+	    << miph->seqno() << "] to " << PRINTADDR(iph->daddr()) << "\n";
+	   break;
+
+	default:
+	   cout << "+ " << node_info_ << " " << MYNUM 
+	   << " send BU [" << miph->seqno() 
+	   << "] to " << PRINTADDR(iph->daddr()) << "\n";
+	   break;
+	}
+   }
+   send(p, 0); 
+}
+
+// *************************************************************************
+// XXX: temporary.
+// Encapsulator should make use of Binding Cache.  This still require
+// some modification.  Will do it later.
+// *************************************************************************
+void MIPv6Agent::encap_route(int fromaddr, int toaddr, double lft)
+{
+   Tcl& tcl = Tcl::instance();
+   tcl.evalf("%s encap-route %d %d %lf", name_, fromaddr, toaddr, lft);
+}
+
+// *************************************************************************
+// *************************************************************************
+void MIPv6Agent::delete_route(int addr) 
+{
+   Tcl& tcl = Tcl::instance();
+   tcl.evalf("%s clear-reg %d", name_, addr);
+}
+
+// *************************************************************************
+// *************************************************************************
+void MIPv6Agent::decap_route(int addr, double lft) 
+{
+// XXX: MN as it is built in TCL does not need a call to decap-route
+// XXX: since packets are encapsulated to port DECAP_PORT (=1)
+// XXX: Decapsulator handles packet to the default target i.e. node entry. 
+// Tcl& tcl = Tcl::instance();
+// tcl.evalf("%s decap-route %d %lf", name_, addr, lft);
+}
+
+// *************************************************************************
+// CN or former default router (previous BS) is instructed 
+// to redirect DTG towards current COA
+// If CoA = Home Address, this is a de-registration (probably back to home)
+// *************************************************************************
+void MIPv6Agent::mn_registration(Packet *p)
+{
+   hdr_mipv6 *miph = HDR_MIPv6(p);
+
+   if (miph->coa() == miph->haddr()) { 
+     // De-registration 
+     print_info(p, '-', "DEREG");
+     update_bcache(p, OFF);
+   }
+   else {
+     // Registration 
+     print_info(p, '-', "REG");
+     update_bcache(p, ON);
+   }    
+   if (miph->A() == ON)
+	send_ack(p);
+}
+
+// *************************************************************************
+// *************************************************************************
+void MIPv6Agent::send_ack(Packet *p)
+{
+   hdr_mipv6 *miph = HDR_MIPv6(p);
+   send_packet(set_ack_packet(miph->haddr(), miph->coa(), miph->seqno()));
+}
+
+// *************************************************************************
+// Set the packet containing the Binding Acknowledgment
+// *************************************************************************
+Packet* MIPv6Agent::set_ack_packet(int final_dst, int via_hop, int seqno)
+{
+   Packet *p = allocpkt();
+   set_ipv6_hdr(p, final_dst);   
+   set_back_hdr(p, seqno);     
+   return(p);
+}
+
+// *************************************************************************
+// Fill the Binding Acknowledgment Option
+// *************************************************************************
+void MIPv6Agent::set_back_hdr(Packet *p, int seqno)
+{
+   hdr_mipv6 *h = HDR_MIPv6(p);
+   hdr_cmn *hdrc = HDR_CMN(p);
+
+   hdrc->size() += BACK_SIZE;
+   hdrc->ptype() = PT_BACK;
+   h->type() = BACK;
+   h->seqno() = seqno;
+   h->lifetime() = 0; 
+}
+
+// *************************************************************************
+// Fill the IPv6 header
+// *************************************************************************
+void MIPv6Agent::set_ipv6_hdr(Packet *p, int dst)
+{
+   hdr_cmn *hdrc = HDR_CMN(p);
+
+   // saddr() is set in Agent::initpkt
+   // Rewrite IPv4 header size set in Packet::initpkt 
+   hdrc->size() = IPv6_HEADER_SIZE;
+   hdr_ip *iph = HDR_IP(p);
+   iph->daddr() = dst;
+   iph->dport() = port();
+}
+
+// *************************************************************************
+// Fill the Routing header
+// XXX: Now useless: done by SrcRouting which adds Routing Header
+// *************************************************************************
+/*
+void MIPv6Agent::set_routing_hdr(Packet *p, int final_dst, int via_hop)
+{
+   hdr_mipv6 *h = HDR_MIPv6(p);
+   hdr_cmn *hdrc = HDR_CMN(p);
+   hdrc->size() += ROUTE_HDR_SIZE;
+   h->haddr() = final_dst;
+   h->coa() = via_hop;
+}
+*/
+
+// *************************************************************************
+// Print info to follow up how the protocole behave  
+// c: '+' indicates send packet / '-' indicates received.
+// *************************************************************************
+void MIPv6Agent::print_info(Packet *p, char c, char *txt) 
+{
+   hdr_mipv6 *miph = HDR_MIPv6(p);
+
+   if (print_info_) {
+      cout << c << " " << node_info_ << " " << MYNUM << " " << txt 
+      << " BU [" << miph->seqno() << "] from " << PRINTADDR(miph->haddr())
+      << " (" << PRINTADDR(miph->coa()) << ")" << " at " << NOW << "\n";
+   }
+}
+
+// *************************************************************************
+int MIPv6Agent::command(int argc, const char*const* argv)
+{
+   if (argc == 2) {
+      if (strcmp(argv[1], "dump") == 0) {
+	dump();
+	return TCL_OK;
+      }
+   }
+   if (argc == 3) {
+	if (strcmp(argv[1], "bcast-target") == 0) {
+		bcast_target_ = (NsObject *)TclObject::lookup(argv[2]);
+		return TCL_OK;
+	}
+   }
+   return (Agent::command(argc, argv));
+}
+
+// *************************************************************************
+// Print:
+// Binding Cache
+// *************************************************************************
+void MIPv6Agent::dump()
+{
+   dump_list(head(bcache_head_), "Binding Cache");
+}
+
+// *************************************************************************
+// Print the content of the list
+// All lists have the same format
+// *************************************************************************
+void MIPv6Agent::dump_list(Entry *node, char *txt) {
+
+   if ( node ) {
+	cout << "\n|" << txt << " for node " << PRINTADDR(addr())
+	<<  " at " << NOW << " --------------------------------------- |\n";
+	cout << "|Node\t\tCOA\t\tType\tInfo\tFlag\tLast\tTime\t\tLife\t"
+	<< "Expire\t\tNb|\n"; 
+
+	for ( ; node; node = node->next_entry()) {
+	
+     	  cout << "|" <<  PRINTADDR(node->addr) << "\t\t" 
+	  << PRINTADDR(node->caddr) << "\t\t" << node->type 
+     	  << "\t" << node->info << "\t" << node->flag  << "\t"
+     	  << node->seqno  << "\t" << node->time << "\t\t"
+	  << node->lifetime() << "\t" 
+	  << node->active_expire << "\t\t" << node->nbbu << " |\n";
+        }
+	cout << "\n";
+   }
+}
+
+// *************************************************************************
+// Search for an entry in the list pointed by its first element 
+// *************************************************************************
+Entry* MIPv6Agent::lookup_entry(int addr, Entry *n)
+{
+   for ( ; n ; n=n->next_entry()) {
+       if(n->addr == addr)
+             return n;
+   }
+   return NULL;
+}
+
+// *************************************************************************
+// Add a new node in the Binding Cache
+// XXX: Binding Cache should be used by Encapsulator and Decapsulator objects
+// XXX  direclly - this will be added later.
+// XXX  Now, Binding Cahce is only used to dump what is received by a node 
+// *************************************************************************
+Entry* MIPv6Agent::update_bcache(Packet *p, int flag)
+{
+   hdr_mipv6 *h = HDR_MIPv6(p);
+
+   // Check if an entry does already exists for the source address
+   Entry *n = lookup_entry(h->haddr(), head(bcache_head_));
+
+   if ( !n ) {
+      n = new Entry(h->haddr(), BU_MN, flag);
+      n->insert_entry(&bcache_head_);
+   }
+
+   if ( flag == ON )
+     encap_route(h->haddr(), h->coa(), h->lifetime());
+   else 
+     delete_route(h->haddr());
+   n->update_entry(h->seqno(), h->haddr(), h->coa(), NOW, h->lifetime());
+   
+   return n;
+}
+
+// *************************************************************************
+// >----------------------------------------------------------------------<
+// MIPv6 Base Stations and Home Agent
+// >----------------------------------------------------------------------<
+// *************************************************************************
+static class BSAgentClass : public TclClass {
+public:
+	BSAgentClass() : TclClass("Agent/MIPv6/BS") {}
+	TclObject* create(int, const char*const*) {
+		return (new BSAgent());
+	}
+} class_bsagent;
+
+// *************************************************************************
+BSAgent::BSAgent() : MIPv6Agent(), timer_(this), 
+adlftm_(~0), rseq_(0), ragent_(0)
+{
+	bind("ad_lifetime_", &adlftm_);
+	strcpy(node_info_, "BS");
+}
+
+// *************************************************************************
+void BSAgent::timeout(int )
+{
+	send_ads();
+	timer_.resched(Random::uniform(0, beacon_));
+	//timer_.resched(beacon_);
+}
+
+// *************************************************************************
+int BSAgent::command(int argc, const char*const* argv)
+{
+	if (argc == 2) {
+		if (strcmp(argv[1], "stop-beacon") == 0) {
+			timer_.cancel();
+			return TCL_OK;
+		}
+		else if (strcmp(argv[1], "start-beacon") == 0) {
+			timer_.resched(Random::uniform(0, beacon_));
+			return TCL_OK;
+		}
+      		else if (strcmp(argv[1], "dump") == 0) {
+			dump();
+			return TCL_OK;
+		}
+	}
+	if (argc == 3) {
+		if (strcmp(argv[1], "set-beacon-period") == 0) {
+			beacon_ = atof(argv[2]);
+			return TCL_OK;
+		}
+		if (strcmp(argv[1], "beacon-period") == 0) {
+			beacon_ = atof(argv[2]);
+			timer_.resched(Random::uniform(0, beacon_));
+			return TCL_OK;
+		}
+		if (strcmp(argv[1], "ragent") == 0) {
+		  	ragent_ = (NsObject *)TclObject::lookup(argv[2]);
+			return TCL_OK;
+		}
+	}
+	return (Agent::command(argc, argv));
+}
+
+// *************************************************************************
+// Beacons are always broadcast packets
+// XXX: should be done in the NETWORK Agent, not in MIP - just needs an API
+// *************************************************************************
+void BSAgent::send_ads()
+{
+   Packet *p = allocpkt();
+   hdr_ip *iph = HDR_IP(p);
+   hdr_rtads *rh = HDR_RTADS(p);
+   hdr_cmn *hdrc = HDR_CMN(p);
+
+   iph->daddr() = IP_BROADCAST;
+   iph->dport() = port();
+   hdrc->ptype() = PT_RADS;
+   hdrc->size() = PT_RADS_SIZE;
+
+   if (print_info_) 
+	cout << "+ BS " <<  MYNUM << " send ADS to " 
+	<< PRINTADDR(iph->daddr()) << " at " << NOW << "\n";
+
+   rh->lifetime() = adlftm_;
+
+   //if (bcast_target_) bcast_target_->recv(p, (Handler*) 0);
+   //else if (target_) send(p, 0);
+   //else Packet::free(p);
+   send(p, 0);
+}
+
+
+// *************************************************************************
+// >----------------------------------------------------------------------<
+// Mobile IPv6 Mobile Node 
+// If advertisement from a new BS: Get a new COA
+// Periodically: Register current COA with HA, former BS, and CNs
+// >----------------------------------------------------------------------<
+// *************************************************************************
+
+void BSListTimer::expire(Event *) {
+	a_->timeout(MIP_TIMER_BSLIST);
+}
+
+static class MNAgentClass : public TclClass {
+public:
+	MNAgentClass() : TclClass("Agent/MIPv6/MN") {}
+	TclObject* create(int, const char*const*) {
+		return (new MNAgent());
+	}
+} class_mnagent;
+
+// *************************************************************************
+// MNAgent Creator
+// *************************************************************************
+MNAgent::MNAgent() : MIPv6Agent(), ha_(NONE), bs_(NONE), oldbs_(NONE),
+	coa_(NONE), oldcoa_(NONE), coalost_(TRUE), nbu_(0),
+	reglftm_(~0), adlftm_(0.0), node_ (0), bu_policy_(DEF_BU), 
+	rt_opti_(1), bs_forwarding_(1), decap_port_(-1), 
+	bslist_timer_(this), bu_timer_(this)
+{	
+	// Binding Update List Management 
+        LIST_INIT(&bulist_head_);
+
+	// List of Base Station
+	LIST_INIT(&bslist_head_);
+	
+	// Binding Update History - to collect statistics
+        LIST_INIT(&history_head_);
+
+	bind("max_rate_", &max_rate_);
+	bind("slow_rate_", &slow_rate_);
+	bind("reg_lifetime_", &reglftm_);
+	bind("rt_opti_", &rt_opti_);
+	bind("bs_forwarding_", &bs_forwarding_);
+	m_seqno_ = 0;
+	strcpy(node_info_,"MN");
+}
+
+// *************************************************************************
+// MNAgent Recv
+// *************************************************************************
+void MNAgent::recv(Packet* p, Handler *)
+{
+   hdr_cmn *hdrc = HDR_CMN(p);
+   hdr_ip *iph = HDR_IP(p);
+
+   if (print_info_) 
+	cout << "- " << node_info_ << " "  <<  MYNUM << " at " << NOW 
+	<< " from " << PRINTADDR(iph->saddr());
+ 
+   if (iph->dport() == port() ) {
+     // This packet is intended for MIPv6 specifically
+
+     switch (hdrc->ptype()) {
+      case PT_RADS:
+	   if (print_info_) cout << " -- Router ADS";
+	recv_ads(p);
+	   if (print_info_) cout << "\n";
+	Packet::free(p);
+	break;
+
+      case PT_BU:
+	   if (print_info_) cout << " -- BU\n";
+	// fprintf(stderr, "MIPv6 MN: processing BU from another MN not yet implemented");
+	cout << NOW << " MIPv6 MN: processing BU from another MN not yet implemented\n";
+
+//	exit(1);
+	// recv_bu(p);
+	Packet::free(p);
+	break;
+
+      case PT_BACK:
+	   if (print_info_) cout << " -- BACK\n";
+	recv_back(p);
+	Packet::free(p);
+	break;
+
+      case PT_BREQ:
+	   if (print_info_) cout << " -- BREQ\n";
+	// recv_breq(p);
+	fprintf(stderr, "MIPv6: BINDING REQUEST not yet implemented");
+	exit(1);
+	Packet::free(p);
+	break;
+
+      case PT_SOL:
+           // Recv Solicitation from an other MN - discard   
+           Packet::free(p);
+           break;
+
+      default:
+	fprintf(stderr, "MIPv6: Packet Type %d not supported\n", hdrc->ptype());
+	Packet::free(p);
+	break;
+     } // switch
+
+   } else {
+        // XXX Once we add piggybacking, this should be processed here.
+        // Keep forwarding this packet
+	// send(p, 0);
+	fprintf(stderr, "Piggybacking not yet supported\n");
+	Packet::free(p);
+   }
+}
+
+// *************************************************************************
+// If we received an encapsulated packet, we probably need to send a BU 
+// to sender because it doesn't have the careof-address.
+// *************************************************************************
+void MNAgent::recv_decap(Packet *p)
+{
+/*
+   hdr_ip *iph = HDR_IP(p);
+   if ( iph->daddr() == here_.addr_ ) {
+	add_bulist( iph->saddr(), BU_CN, ON);
+   }
+*/
+}
+
+// *************************************************************************
+// Processing of Binding Acknowledgment    
+// Stop sending BUs if we are back to home and ACK from HA for the right CoA
+// XXX: should do it on a per CN or HA basis, not for everyone.  
+// *************************************************************************
+void MNAgent::recv_back(Packet *p)
+{ 
+   hdr_mipv6 *miph = HDR_MIPv6(p);
+   hdr_ip *iph = HDR_IP(p);
+
+   Entry *n = lookup_entry(iph->saddr(), head(bulist_head_));
+   if ( n != NULL ) {
+      if ( n->seqno == miph->seqno() && n->caddr == coa_ && iph->saddr() == ha_ && coa_ == HADDR) { 
+	if (bu_timer_.status() == TIMER_PENDING) {
+		bu_timer_.cancel();
+	}
+      }
+   }
+}
+
+// *************************************************************************
+// Processing of Router Advertisement
+// *************************************************************************
+void MNAgent::recv_ads(Packet *p)
+{
+   hdr_ip *iph = HDR_IP(p);
+   hdr_rtads *rh = HDR_RTADS(p);
+
+   // We search in list of BSs to check if we know about this BS
+   Entry *node = lookup_entry(iph->saddr(), head(bslist_head_));
+   if ( node ) { 
+      // We already have this BS in the list - Reset its expire time 
+      // No need to send BU 
+
+      node->update_entry(NONE, iph->saddr(), NONE, NOW, rh->lifetime());
+
+   } else { 
+      // New ads.  This BS is not yet recorded in our BS list
+      // Record it in front of list. This BS will become current BS
+      // We need a new COA on the BS's subnet and we need 
+      // to register BS in list and new binding with HA / CN.
+      
+      if (print_info_) cout << " ***  new BS ***"; 
+      Entry *pbs = add_bs(iph->saddr());
+
+      // XXX: I should send a request to obtain a COA 
+      pbs->update_entry(NONE, NONE, get_coa(iph->saddr()), NOW, rh->lifetime());
+      coalost_ = TRUE;
+      reg();
+   }
+}
+
+// *************************************************************************
+// Timer
+// *************************************************************************
+void MNAgent::timeout(int tno)
+{
+   switch (tno) {
+   case MIP_TIMER_BU:
+	// Happens if no BU sent during max_rate_ or slow_rate interval
+	if (print_info_) 
+	   cout << "* MN " << MYNUM << " Timer BU " 
+		<< max_rate_ << " expired at " << NOW << "\n";
+	reg();
+	break;
+
+   case MIP_TIMER_BSLIST: {
+	// Check expiration time for each BS
+	// If expired, delete it since no ads for too long
+	// If this is the current BS, register with a new one.
+
+	if (print_info_) 
+	cout << "* MN " << MYNUM << " Timer BSList expired at " << NOW << "\n";
+
+	// Remove entries that have expired
+	Entry *entry = head(bslist_head_); 
+   	for ( ; entry; entry = entry->next_entry()) {
+	   if (entry->expire() < NOW) {
+	   	if ( entry->caddr == coa_) {
+		   // We have lost the current BS
+		   // We will need to register with a new one 
+		   coalost_ = TRUE;
+		}
+		entry->remove_entry();
+		delete entry;
+	   }
+	}
+	bslist_timer_.resched(beacon_);
+	
+	if (coalost_ == TRUE) {
+	   if (print_info_) cout << "* MN lost contact with current BS" << "\n";
+	   reg();
+	}
+	break;
+   }
+   default:
+	break;
+   }
+}
+
+// *************************************************************************
+// Interface to the OTcl interpreter
+// *************************************************************************
+int MNAgent::command(int argc, const char*const* argv)
+{
+   if (argc == 2) {
+      if (strcmp(argv[1], "dump") == 0) {
+	dump();
+	return TCL_OK;
+      }
+   } else if (argc == 3) {
+      if (strcmp(argv[1], "check-beacon") == 0) {
+	// We check if we are still attached to the BS every <beacon_> sec.
+	beacon_ = atof(argv[2]);
+	timeout(MIP_TIMER_BSLIST);
+	bslist_timer_.resched(beacon_);
+	return TCL_OK;
+      }
+      else if (strcmp(argv[1], "set_max_rate") == 0) {
+	max_rate_ = atof(argv[2]);
+	bu_timer_.resched(max_rate_);
+	return TCL_OK;
+      }
+      else if (strcmp(argv[1], "set_slow_rate") == 0) {
+	slow_rate_ = atof(argv[2]);
+	return TCL_OK;
+      } else if (strcmp(argv[1], "decap-port") == 0) {
+	decap_port_ = atoi(argv[2]);
+	return TCL_OK;
+      } else if (strcmp (argv[1], "node") == 0) {
+	node_ = (MobileNode*)TclObject::lookup(argv[2]);
+	if (node_ == 0) {
+	   fprintf (stderr, "%s: %s lookup of %s failed\n", __FILE__, argv[1], argv[2]);
+	   return TCL_ERROR;
+	}
+	return TCL_OK;
+      }
+      else if (strcmp (argv[1], "add-cn") == 0) {
+	   Entry *nn = add_bulist(atoi(argv[2]), BU_CN, ON);
+           nn->activate_entry(NOW, TIME_INFINITY);
+	   return TCL_OK;
+      }
+      else if (strcmp (argv[1], "remove-cn") == 0) {
+	   remove_bulist(atoi(argv[2]), BU_CN );
+	   return TCL_OK;
+      }
+      else if (strcmp (argv[1], "add-group") == 0) {
+	   Entry *nn = add_bulist(atoi(argv[2]), BU_RP, ON );
+           nn->activate_entry(NOW, TIME_INFINITY);
+	   return TCL_OK;
+      }
+      else if (strcmp(argv[1], "set-ha") == 0) {
+	 Entry *nn = add_bulist(ha_=atoi(argv[2]), BU_HA, ON);
+         nn->activate_entry(NOW, TIME_INFINITY);
+	 return TCL_OK;
+      }
+   }
+   return (Agent::command(argc, argv));
+}
+
+// *************************************************************************
+// Add a new node in the Binding Update List
+// If node already exists, just activate the entry 
+// Node = CN, HA, former BS
+// *************************************************************************
+Entry* MNAgent::add_bulist(int daddr, Mipv6RegType type, int flag)
+{
+   // Check that an entry does not already exists
+   Entry *n = lookup_entry(daddr, head(bulist_head_));
+   if ( n == NULL ) {
+        n = new Entry(daddr, type, flag);
+        n->insert_entry(&bulist_head_);
+   }
+   // In all case, activate the entry and allow BU to be sent until time limit
+   // By default, registration time. 
+   n->activate_entry(NOW, reglftm_); 
+   return n;
+}
+
+// *************************************************************************
+// Remove a node (CN, HA, BS) from the Binding Update List 
+// Indeed, it is moved to the history list for statistics.
+// Could also use	nn->remove_entry(&history_head_);
+// *************************************************************************
+void MNAgent::remove_bulist(int addr, Mipv6RegType type)
+{
+   Entry *node = lookup_entry(addr, head(bulist_head_));
+   if (node && node->type == type) {
+	// Move entry from the Binding List to history
+	node->remove_entry();
+
+        // Chain entry to the history if there exists one (for statistics)
+   	node->insert_entry(&history_head_);
+   }
+}
+
+// *************************************************************************
+// Add new BS in Base Station List 
+// *************************************************************************
+Entry* MNAgent::add_bs(int daddr)
+{
+   // Check if an entry does not already exist
+   Entry *node = lookup_entry(daddr, head(bslist_head_));
+   
+   assert (node == NULL);
+
+   node = new Entry(daddr, BS_ADS, OFF);
+   node->insert_entry(&bslist_head_);
+   return node;
+}
+
+// *************************************************************************
+// Print: 
+// Binding Update List 
+// Base Station List
+// History List
+// *************************************************************************
+void MNAgent::dump()
+{
+   dump_list(head(bulist_head_), "Binding Update List");
+   dump_list(head(bslist_head_), "Base Station List");
+   dump_list(head(history_head_), "History List");
+}
+
+// *************************************************************************
+// Get a new coa on the BS's subnet
+// We need a new COA with same prefix as the new current BS
+// XXX: for now, call TCL interpreter, but we need something like DHCPv6
+// XXX: Interpreter returns a COA with BS's prefix
+// *************************************************************************
+int MNAgent::get_coa(int new_bs)
+{
+   Tcl& tcl = Tcl::instance();
+
+   if ( new_bs == ha_ )
+	// We are back to home.  
+	// We still need to (de-)register with coa = home_address
+	return HADDR;
+   else {
+cout << NOW << " get_coa for BS " << PRINTADDR(new_bs) << ":" << new_bs << "\n";
+	tcl.evalf("%s get-coa %s", name_, PRINTADDR(new_bs) );
+	return(atoi(tcl.result()));
+   }
+}
+
+// *************************************************************************
+// We are now attached to a new subnet 
+// The MNagent now should update the Mobilenode about the changed coa_ 
+// 1. ARP needs to reply to this COA
+// 2. Current BS is needed by Network Agent to set "next_hop"
+// *************************************************************************
+void MNAgent::set_subnet()
+{
+	node_->set_coa(coa_);
+	node_->set_base_stn(bs_);
+	if (print_info_) {
+		cout << " MN " << node_->address();
+		cout << " has COA " << PRINTADDR(node_->coa()) << "\n"; 
+	}
+}      
+
+// *************************************************************************
+// Registration with HA, CNs, previous default router
+// When ?
+// => New BS
+// => Timer has expired
+// => BU Request (XXX: not yet implemented)
+// Send current COA to:
+// - HA: If we are back home, COA would be = home address. Fine. 
+// - Previous BS: unless previous BS is HA or we don't have one 
+// 	XXX: How long should we keep forwarding at previous BS ?
+// - CNs if we have some in the Binding List
+// [MIPv6] says that BUs are generally sent to CNs 
+// when a BU containing a new COA is sent to the HA.
+// Here, we send BUs to CNS whenever we send a BU to HA. 
+// *************************************************************************
+void MNAgent::reg()
+{
+   // Check if we are still attached to a BS
+   if ( ! head(bslist_head_) ) {
+   	// We do not have BS at all in the BS list 
+	bu_timer_.resched(max_rate_);
+	send_sols();
+	return;
+   }
+   
+   // Check if we have an active care-of address
+   if (coalost_ == TRUE) {
+	// We have BSs in the list, but we have lost contact with current BS
+	// because TIMER_BSLIST has expired. 
+	// Choose new BS = first on list since we have deleted the former one 
+	// and register with it                         
+
+        // Stop sending BUs at "previous previous" BS if still in BU List 
+	// XXX: this should be automatic - we don't keep it very long (?)
+        remove_bulist(oldbs_, BU_BS);
+
+	Entry *pbs = head(bslist_head_); 
+	oldbs_ = bs_;
+	bs_ = pbs->addr;
+	oldcoa_ = coa_; 
+	coa_ = pbs->caddr;
+	adlftm_ = pbs->lifetime();
+      
+	// Set the new BS as the gateway to the Internet
+	set_subnet();
+	coalost_ = FALSE;
+	nbu_ = 0; 
+
+	// We need to establish forwarding from previous BS
+	// if there is one
+	// NOTE: if previous BS is HA, add_bulist already have
+	// an entry and won't add a new one
+	// XXX: if ( oldbs_ != NONE && oldbs_ != ha_ ) {
+	if ( oldbs_ != NONE ) {
+		Entry *nn = add_bulist(oldbs_, BU_BS, ON);
+		nn->update_entry(NONE, oldcoa_, coa_, NOW, reglftm_);
+	}
+   }
+
+   // As specified in Mobile IPv6, periodic BU should be sent 
+   // with longer interval after 5 transmissions
+   if ( nbu_++ < MAX_FAST_UPDATES ) 
+	bu_timer_.resched(max_rate_);
+   else
+	bu_timer_.resched(slow_rate_);
+
+   send_standard_bu(BU_HA);
+   if ( rt_opti_ ) send_standard_bu(BU_CN);
+   if ( bs_forwarding_) send_standard_bu(BU_BS);
+}
+
+// *************************************************************************
+// Send standard Mobile IPv6 Binding Update  
+// XXX: Here, we may decide to send BUs to CNs and HAs at 
+// XXX: different frequency, depending on local policy
+// XXX: For now, send BU to everyone at the same time
+// *************************************************************************
+void MNAgent::send_standard_bu(Mipv6RegType type) 
+{
+   Entry *n = head(bulist_head_); 
+   Entry *nn;
+   Packet *p;
+   hdr_mipv6 *h;
+   while ( n ) { 
+      nn=n;	
+      n=n->next_entry();
+      if ( nn->activated(NOW) && (nn->type == type) ) {
+	p = set_bu_packet(type, nn->addr, coa_);
+	h = HDR_MIPv6(p);
+
+	// Update Binding Update List
+	nn->update_entry(h->seqno(), h->haddr(), h->coa(), NOW, h->lifetime());
+	send_packet(p);
+      }
+   }
+}
+
+// *************************************************************************
+// Fill Binding Update = IPv6 header + Binding Update Option header
+// *************************************************************************
+Packet* MNAgent::set_bu_packet(Mipv6RegType type, int dst, int newad)
+{
+        Packet *p = allocpkt();
+	set_ipv6_hdr(p, dst);	
+	set_bu_hdr(p, type, newad);	
+	return(p);
+}
+
+// *************************************************************************
+// Fill the Binding Update Option Header 
+// *************************************************************************
+void MNAgent::set_bu_hdr(Packet *p, Mipv6RegType type, int newad) 
+{
+	hdr_cmn *hdrc = HDR_CMN(p);
+        hdr_mipv6 *h = HDR_MIPv6(p);
+	
+	// By default, set flags to OFF.
+	h->H() = OFF;
+	h->A() = OFF;
+	
+	if ( type != BU_BS ) {
+        	h->haddr() = HADDR; 
+	}
+	else {
+        // Former BS establish forwarding from previous coa to new coa
+	// XXX: we should better take the address recorded in BU List
+		h->haddr() = oldcoa_;
+	}
+
+	if ( type == BU_HA ) {
+		h->H() = ON;
+		h->A() = ON;
+	}
+        h->coa() = newad;
+        h->type() = BU;
+        h->lifetime() = LIFETIME;
+	h->seqno() = ++m_seqno_;
+   
+	hdrc->size() += BU_SIZE;
+	hdrc->ptype() = PT_BU;
+}
+
+// *************************************************************************
+// When the MN does not have a registered BS, it needs to enquire for one
+// XXX: should be done in the NETWORK Agent, not in MIP - just needs an API
+// *************************************************************************
+void MNAgent::send_sols()
+{
+   Packet *p = allocpkt();
+   hdr_ip *iph = HDR_IP(p);
+   hdr_mipv6 *h = HDR_MIPv6(p);
+   hdr_cmn *hdrc = HDR_CMN(p);
+
+   h->haddr() = HADDR;
+   hdrc->ptype() = PT_SOL;
+   iph->daddr() = IP_BROADCAST;
+   iph->dport() = port();
+   hdrc->size() = PT_RSOL_SIZE;
+
+   if (print_info_) cout << "+ MN send SOLICITATION at " << NOW << "\n";
+
+   if (bcast_target_) bcast_target_->recv(p, (Handler*) 0);
+   else if (target_) send(p, 0);
+   else Packet::free(p);
+}
+
+// *************************************************************************
+// >----------------------------------------------------------------------<
+// Mobile IPv6 Correspondent Node
+// >----------------------------------------------------------------------<
+// *************************************************************************
+static class CNAgentClass : public TclClass {
+public:
+        CNAgentClass() : TclClass("Agent/MIPv6/CN") {}
+        TclObject* create(int, const char*const*) {
+                return (new CNAgent());
+        }
+} class_cnagent;
+
+// *************************************************************************
+CNAgent::CNAgent() : MIPv6Agent(), timer_(this) 
+{
+   strcpy(node_info_,"CN");
+}
+
+// *************************************************************************
+void CNAgent::timeout(int tno)
+{
+//      timer_.resched(lifetime);
+//      send_request();
+}
+
+// *************************************************************************
+int CNAgent::command(int argc, const char*const* argv)
+{
+  if (argc == 2) {
+      if (strcmp(argv[1], "dump") == 0) {
+        dump();
+        return TCL_OK;
+      }
+   }
+   return (Agent::command(argc, argv));
+}
+
+// *************************************************************************
+// Print:
+// Binding Cache
+// *************************************************************************
+void CNAgent::dump()
+{
+   dump_list(head(bcache_head_), "Binding Cache");
+}
diff -urNU5 ns-2.33/mobiwan/mipv6.h ns-2.33-mobiwan/mobiwan/mipv6.h
--- ns-2.33/mobiwan/mipv6.h	1970-01-01 10:00:00.000000000 +1000
+++ ns-2.33-mobiwan/mobiwan/mipv6.h	2008-05-06 14:40:09.000000000 +1000
@@ -0,0 +1,378 @@
+/* This software comprises contributed code made by Motorola, as a 
+ * Contributor, to Network Simulator NS-2 software provided by the 
+ * Regents of the University of California.
+ * (Copyright; Regents of the University of California, 1994)
+ * The contributed code was made as a result of a partnership between 
+ * Motorola and INRIA Rhone-Alpes. 
+ *
+ * Copyright in the contributed code belongs to Motorola Inc. 2001
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ALL ADVERTISING MATERIALS MENTIONING FEATURES OR USE OF THIS SOFTWARE MUST 
+ * DISPLAY AN ACKNOWLEDGEMENT TO THE COPYRIGHT OWNERS. 
+ * ANY REDISTRIBUTION OF THIS SOFTWARE MUST CONTAIN THE ABOVE COPYRIGHT NOTICES, 
+ * CONDITIONS AND DISCLAIMER.
+ */
+
+/* ############################################################################
+ * This code was developed by Thierry Ernst (1998-2001)
+ * MOTOROLA Labs Paris FRANCE - INRIA Rhone-Alpes Grenoble (PLANETE) FRANCE 
+ * NS-2.1b6 enhancements for Wide-Area mobility simulations
+ * ############################################################################
+ */
+
+// *************************************************************************
+//                              mipv6.h  
+//      Mobility Support in IPv6 
+//      Based on <draft-ietf-mobileip-ipv6-11.txt> March 2000 with some
+//      simplifications.
+//
+// **************************************************************************
+#ifndef ns_mipv6_h
+#define ns_mipv6_h
+
+//#include "list.h"
+#include "../mobile/mip.h"
+
+// **************************************************************************
+// Mobile IPv6 Default Settings
+// **************************************************************************
+#define	MIP_TIMER_BU		0
+#define	MIP_TIMER_BSLIST	1	
+#define	NONE			-1
+
+#define	INITIAL_BINDACK_TIMEOUT	1	// sec
+#define	MAX_BINDACK_TIMEOUT	256	// sec
+#define	MAX_UPDATE_RATE		1	// sec
+#define	SLOW_UPDATE_RATE	10	// sec
+#define	MAX_FAST_UPDATES	5	// transmissions
+#define	MAX_ADVERT_REXMIT	3	// transmissions
+
+#define BU_OPT_SIZE		10		// + sub_option
+#define BU_ACK_OPT_SIZE		13		// + sub_option 
+#define	BU_REQ_OPT_SIZE		2		// + sub_option
+#define HOME_OPT_SIZE		18		// + sub_option  
+#define	BU_SIZE	   DEST_HDR_PREFIX_SIZE + BU_OPT_SIZE + HOME_OPT_SIZE
+#define BACK_SIZE  DEST_HDR_PREFIX_SIZE + BU_ACK_OPT_SIZE
+#define BREQ_SIZE  DEST_HDR_PREFIX_SIZE + BU_REQ_OPT_SIZE	
+
+typedef enum {
+	BREQ, BU, BACK, 
+	BU_HA, BU_BS,  BU_CN, BU_RP, BU_MN,
+	BS_ADS, BS_SOL
+} Mipv6RegType;
+
+typedef enum {
+        DEF_BU, LBM_BU, MBU_CN, MBU_ALL, LBM_BU_ALL, LBM_BU_CN, TEST
+} IPv6OptionType;
+
+#define ON			1	
+#define OFF			0
+
+// #define LIFETIME		min(reglftm_, adlftm_)
+#define LIFETIME		reglftm_
+
+#define TIME_INFINITY		0x0fffffff			
+
+// **************************************************************************
+// Binding Update List
+// **************************************************************************
+class Entry;
+LIST_HEAD(entry, Entry);
+
+class Entry {
+ public:
+        Entry(int address, Mipv6RegType t, int f)  { 
+		addr = address;	
+		haddr = -1;
+		caddr = -1;
+		seqno = -1; 
+		flag  = f;
+		lftm = 0;  
+		time = -1;		
+		active_expire = 0;
+		nbbu = 0;
+		type = t;
+		
+		switch ( t ) {
+		   case BU_HA:
+			strcpy(info, "HA");   break;
+		   case BU_BS:
+			strcpy(info, "BS");   break;
+		   case BU_MN:
+			strcpy(info, "MN");   break;
+		   case BS_ADS:
+			strcpy(info, "BS");   break;
+		   case BU_RP:
+			strcpy(info, "RP");   break;
+		   default:
+			strcpy(info, "CN");   break;
+		}	
+	}  
+        ~Entry() { ; }
+
+	// Chain element to the list
+	inline void insert_entry(struct entry *head) {
+        	LIST_INSERT_HEAD(head, this, link);
+	}
+
+	inline void update_entry(int seq, int h, int c, double t, double life) {
+		seqno=seq;
+		haddr=h;
+		if ( c != NONE ) caddr=c;
+		time=t;
+		lftm=life;
+		nbbu++;
+		flag=ON;
+	}
+	inline double expire() { return (time + lftm) ; }
+	inline double& lifetime() { return lftm; }
+	inline int activated(double now) { 
+		return ( (flag==ON) && (now<active_expire)) ? TRUE : FALSE; 
+	}
+	
+	inline void activate_entry(double now, double life) {
+	// We want to send BU and we want to keep doing this
+	// until current time > active_expire_time 
+		flag=ON;
+		if ( (now+life) > active_expire) active_expire = now + life ;
+	}
+
+	// Return next element in the chained list
+        Entry* next_entry(void) const { return link.le_next; }
+	
+	inline void remove_entry() { LIST_REMOVE(this, link); }
+
+	inline void remove_entry(struct entry *newhead) {
+	    LIST_REMOVE(this, link);
+            LIST_INSERT_HEAD(newhead, this, link);
+	}
+
+	inline void deactivate_entry() {
+		// We don't want to send BU to this node anymore
+		// but we want to keep it in the list
+		flag=OFF;
+	}
+	// Fields as described in the Mobile IPv6 spec.
+       	int 		addr;		// address (key)
+	int 		haddr;		// Last Home address sent
+        int       	caddr;		// Last COA sent 
+	double		lftm; 		// lifetime of this entry 
+	double		time; 		// time at which entry was updated 
+        int       	seqno;		// Last BU's sequence number
+        int       	flag;		// Do not send BU if set to ON 
+
+	// XXX: Other fields that may be included as in the spec: 
+	// int       	state;		// State of retransmission
+
+	// For statistic and display purposes only  
+	double		active_expire;	// term of activation
+	int 		nbbu;		// Total nb BU sent to this node
+	Mipv6RegType	type;		// BU_HA / BU_CN / BU_REDIRECT ...  
+	char		info[10];	// To distinguish between CN, HA, BS
+
+ protected:
+        LIST_ENTRY(Entry) link;
+}; 
+
+// **************************************************************************
+// MIPv6 messages
+// **************************************************************************
+//b7: #define HDR_MIPv6(p)      (hdr_mipv6::access(p))
+#define HDR_MIPv6(p)	((struct hdr_mipv6*)(p)->access(hdr_mipv6::offset_))
+struct hdr_mipv6 {
+	Mipv6RegType optype_;
+	int A_;			// Ack required bit 
+	int H_;			// Home registration bit
+	int seq_; 
+	double lftm_; 
+	int homeaddr_;
+	int coaddr_;	
+
+	// XXX: Following will be needed for ns-2b.7 with some modification
+	// - required by PacketHeaderManager
+	static int offset_;
+        inline static int& offset() { return offset_; }
+        inline static hdr_mipv6* access(Packet* p) {
+                return (hdr_mipv6*) p->access(offset_);
+        }
+
+	// New 02/01
+ 	inline Mipv6RegType& type() { return optype_; }
+ 	inline int& A() { return A_; }
+ 	inline int& H() { return H_; }
+ 	inline int& seqno() { return seq_; } 
+ 	inline double& lifetime() { return lftm_; }
+ 	inline int& coa() { return coaddr_; }
+        inline int& haddr() { return homeaddr_; }
+};
+
+// **************************************************************************
+// Timers
+// **************************************************************************
+class BUTimer : public TimerHandler {
+ public:
+        BUTimer(Agent *a) : TimerHandler() { a_ = a; }
+ protected:
+        inline void expire(Event *) { a_->timeout(MIP_TIMER_BU); }
+        Agent *a_;
+};
+
+// Timer to reset BS's advertisement recorded at MN
+class MNAgent;
+class BSListTimer : public TimerHandler {
+ public: 
+        BSListTimer(MNAgent *a) : TimerHandler() { a_ = a; }
+ protected:
+        void expire(Event *e);
+        MNAgent *a_;
+};
+
+// **************************************************************************
+// Mobile IPv6 Base Agent
+// **************************************************************************
+class MIPv6Agent : public Agent {
+public:
+	MIPv6Agent();
+	struct entry bcache_head_;	
+protected:
+	int command(int argc, const char*const*argv);
+	NsObject *bcast_target_; 	// where to send solicitations / ads
+	BUTimer timer_;
+	double beacon_;			// Beacon interval
+	int print_info_;
+	char	node_info_[8];
+
+	void send_packet(Packet *p);
+	void set_ipv6_hdr(Packet *p, int);	
+	void send_ack(Packet *p);
+	Packet* set_ack_packet(int, int, int);
+	void set_back_hdr(Packet *p, int);
+	void encap_route(int, int, double);
+	void decap_route(int, double);
+	void delete_route(int);
+	void print_info(Packet *p, char, char *);
+	void recv(Packet *, Handler *);
+	void mn_registration(Packet *p); 
+	virtual void send_ads() { 
+	        fprintf(stderr, "%s: Router Ads not allowed",node_info_); 
+	}
+	// Binding Cache
+	Entry* update_bcache(Packet *, int);
+ 	// Entry* bcache_head()	{ return bcach_head_.lh_first; }
+
+	// List Management
+	Entry* lookup_entry(int, Entry *);	
+ 	Entry* head(struct entry head) { return head.lh_first; }
+
+	// Display
+	void dump();
+	void dump_list(Entry *, char *);
+
+};
+
+// **************************************************************************
+// Base Station Node (+HA)
+// **************************************************************************
+class BSAgent : public MIPv6Agent {
+public:
+	BSAgent();
+	// virtual void recv(Packet *, Handler *);
+	void timeout(int);
+protected:
+	int command(int argc, const char*const*argv);
+	void send_ads();
+	BUTimer timer_;
+	double adlftm_;			// Router Advertisement lifetime 
+	int rseq_;			// sequence number for routing ads
+	NsObject *ragent_;     		// Routing or Network Agent 
+};
+
+// **************************************************************************
+// Mobile IPv6 Node
+// **************************************************************************
+class MNAgent : public MIPv6Agent {
+public:
+	MNAgent();
+	void recv(Packet *, Handler *);
+	void timeout(int);
+	struct entry bulist_head_;	
+	struct entry bslist_head_;	
+	struct entry history_head_;	
+
+	void dump();
+
+	// Binding Update List
+	Entry* add_bulist(int, Mipv6RegType, int);
+protected:
+	int command(int argc, const char*const*argv);
+	void recv_ads(Packet *);
+	void recv_decap(Packet *);
+	void recv_back(Packet *);
+	void set_subnet();
+	int get_coa(int);
+	void reg();
+	void send_sols();
+	int ha_;
+	int bs_;
+	int oldbs_;  
+	int coa_;
+        int oldcoa_;
+	int coalost_;
+	int nbu_;
+	double max_rate_;		// Max Binding Update interval
+	double slow_rate_;		// Slow Binding Update interval
+	int m_seqno_;		/* current registration seqno */
+	double reglftm_;	/* registration lifetime */
+	double adlftm_;		/* advertisement lifetime */
+	MobileNode *node_;      /* ptr to my mobilenode,if appl. */
+	int bu_policy_;	
+	int rt_opti_;		// Route Optimization
+	int bs_forwarding_;	// Previous BS forwarding
+	int decap_port_;
+
+	void send_standard_bu(Mipv6RegType type);
+	Packet* set_bu_packet(Mipv6RegType, int, int);	
+	void set_bu_hdr(Packet *p, Mipv6RegType, int);	
+
+	// Base Station List
+ 	// Entry* bslist_head()	{ return bslist_head_.lh_first; }
+	Entry* add_bs(int);
+	BSListTimer bslist_timer_;
+
+	// Binding Update List
+ 	// Entry* bulist_head()	{ return bulist_head_.lh_first; }
+	BUTimer bu_timer_;
+	void remove_bulist(int,  Mipv6RegType);
+
+	// Display
+	// void dump();
+};
+
+// **************************************************************************
+// Mobile IPv6 Correspondent Node
+// **************************************************************************
+class CNAgent : public MIPv6Agent {
+public:
+        CNAgent();
+      //  void recv(Packet *, Handler *);
+        void timeout(int);
+protected:
+        int command(int argc, const char*const*argv);
+        SimpleTimer timer_;
+
+	// Display
+	void dump();
+};
+
+#endif
diff -urNU5 ns-2.33/tcl/lib/ns-address.tcl ns-2.33-mobiwan/tcl/lib/ns-address.tcl
--- ns-2.33/tcl/lib/ns-address.tcl	2008-04-01 13:00:23.000000000 +1100
+++ ns-2.33-mobiwan/tcl/lib/ns-address.tcl	2008-05-06 14:40:09.000000000 +1000
@@ -108,10 +108,11 @@
 #		  equal to the existing portsize.
 #               * if # hierarchy levels donot match with #bits specified (for
 #                 each level). 
 
 Class AllocAddrBits
+#Class AddrParams
 
 Simulator proc address-format {} {
 	return [Simulator set AddressFormat_]
 }
 
@@ -156,11 +157,15 @@
 }
 
 Simulator instproc set-hieraddress {hlevel args} {
 	set a [$self get-AllocAddrBits "new"]
 	$a set size_ [AllocAddrBits set MAXADDRSIZE_]
+    
 	# By default, setting hierarchical addressing turns on hier rtg
+    if {$hlevel > 1} {
+	Simulator set EnableHierRt_ 1
+    }
 	Simulator set AddressFormat_ HIER
 	Node enable-module "Hier"
 	if [$self multicast?] {
 		$a set-mcastbits 1
 	}
@@ -279,12 +284,12 @@
 		# assert {$chk == 0} --> assert doesn't seem to work
 		error "set-mcastbits: size_ has been changed."
 	}
 	set a [$self get-AllocAddr] 
 	set v [$a setbit $bit_num $size_]
-	AddrParams McastMask [lindex $v 0]
-	AddrParams McastShift [lindex $v 1]
+    AddrParams set McastMask [lindex $v 0]
+    AddrParams set McastShift [lindex $v 1]
 	### TESTING
 	# set mask [lindex $v 0]
 	# set shift [lindex $v 1]
 	# puts "Mcastshift = $shift \n McastMask = $mask\n"
 
@@ -334,11 +339,11 @@
 }
 
 
 # Create an integer address from addr string 
 AddrParams proc addr2id addrstr {
-	if [Simulator hier-addr?] {
+    if [Simulator set EnableHierRt_] {
 		set addressObj [[[Simulator instance] get-AllocAddrBits ""] \
 				get-Address]
 		return [$addressObj str2addr $addrstr]
 	} else {
 		return [expr $addrstr & [AddrParams NodeMask 1] << \
@@ -386,5 +391,92 @@
 			incr C
 		}
 		return [lindex $nodes_num_ [expr $index + [lindex $L 1]]]
 	}
 }
+
+##########################################
+# MOBIWAN Extensions
+# 
+# Modified for Mobiwan in ns-2.26 by WMC(mobiwan@ti-wmc.nl) -11/04
+# Licensed as in header of mipv6.cc
+##########################################
+
+### Hierarchical routing support
+
+#
+# create a real hier address from addr string
+#
+
+
+AddrParams proc set-hieraddr addrstr {
+
+    set ns [Simulator instance]
+    set addressObj [[$ns get-AllocAddrBits ""] get-Address]
+    set ip [$addressObj str2addr $addrstr]
+    
+    return $ip
+}
+
+#
+# returns address string from address :reverse of set-hieraddr.
+#
+AddrParams proc get-hieraddr addr {
+    AddrParams instvar hlevel_ NodeMask NodeShift
+    for {set i 1} {$i <= $hlevel_} {incr i} {
+        set a [expr [expr $addr >> [AddrParams NodeShift $i]] & [AddrParams NodeMask $i]]
+        lappend str $a
+    }
+    #puts "get-hieraddr: string=$str\n"
+    return $str
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Simulator instproc get-node-by-addr address
+# Enhanced to return Mobile Node's address
+# MNs are recorded in array MNode_
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Simulator instproc get-node-by-addr address {
+    $self instvar Node_ MNode_
+    set n [Node set nn_]
+    for {set q 0} {$q < $n} {incr q} {
+	if [info exists Node_($q)] {
+	    set nq $Node_($q)
+	    if {[string compare [$nq node-addr] $address] == 0} {
+		return $nq
+	    }
+	} else {
+	    set nq $MNode_($q)
+	    if {[string compare [$nq node-addr] $address] == 0} {
+		return $nq
+	    }
+	}
+    }
+    error "get-node-by-addr:Cannot find node with given address"
+}
+
+#
+# Given an node's address, Return the node-id
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Simulator instproc get-node-id-by-addr address
+# Enhanced to return Mobile Node's id
+# MNs are recorded in array MNode_
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Simulator instproc get-node-id-by-addr address {
+    $self instvar Node_ MNode_
+    set n [Node set nn_]
+    for {set q 0} {$q < $n} {incr q} {
+	if [info exists Node_($q)] {
+	    set nq $Node_($q)
+	    if {[string compare [$nq node-addr] $address] == 0} {
+		return $q
+	    }
+	} else {
+	    set nq $MNode_($q)
+	    if {[string compare [$nq node-addr] $address] == 0} {
+		return $q
+	    }
+	}
+    }
+    error "get-node-id-by-addr:Cannot find node with given address"
+}
diff -urNU5 ns-2.33/tcl/lib/ns-default.tcl ns-2.33-mobiwan/tcl/lib/ns-default.tcl
--- ns-2.33/tcl/lib/ns-default.tcl	2008-04-01 13:00:23.000000000 +1100
+++ ns-2.33-mobiwan/tcl/lib/ns-default.tcl	2008-05-06 14:40:09.000000000 +1000
@@ -563,18 +563,25 @@
 Node/MobileNode set delay_				0	;# not used
 Node/MobileNode set REGAGENT_PORT 0
 Node/MobileNode set DECAP_PORT 1
 
 
+# MIP Decapsulator
+#Classifier/Addr/MIPDecapsulator set off_ipinip_ 0
+#Classifier/Addr/MIPDecapsulator set off_ip_ 0
+# SRCRouting
+
+SrcRouting set debug_ false 
+
 # Default settings for Hierarchical topology
 #
 # Bits are allocated for different fields like port, nodeid, mcast, 
 # hierarchical-levels. 
 # All Mask and Shift values are stored in Class AddrParams.
 AddrParams set ALL_BITS_SET 0xffffffff
-AddrParams PortShift 0
-AddrParams PortMask [AddrParams set ALL_BITS_SET]
+#AddrParams PortShift 0
+#AddrParams PortMask [AddrParams set ALL_BITS_SET]
 AddrParams set domain_num_ 1
 AddrParams set def_clusters 4
 AddrParams set def_nodes 5
 
 ####  Default and Maximum Address space - leaving the MSB as signed bit
@@ -642,10 +649,14 @@
 MIPEncapsulator set port_ 0
 MIPEncapsulator set shift_ 0
 MIPEncapsulator set mask_ [AddrParams set ALL_BITS_SET]
 MIPEncapsulator set ttl_ 32
 MIPEncapsulator set debug_ false
+#MIPEncapsulator set off_ip_ 0
+#MIPEncapsulator set off_ipinip_ 0
+
+#Agent/Network/NetworkMN set off_ipinip_ 0
 
 # GAF
  
 GAFPartner set addr_ 0
 GAFPartner set port_ 254
diff -urNU5 ns-2.33/tcl/lib/ns-lib.tcl ns-2.33-mobiwan/tcl/lib/ns-lib.tcl
--- ns-2.33/tcl/lib/ns-lib.tcl	2008-04-01 13:00:23.000000000 +1100
+++ ns-2.33-mobiwan/tcl/lib/ns-lib.tcl	2008-05-06 14:41:54.000000000 +1000
@@ -129,10 +129,11 @@
 
 #
 # XXX Whenever you modify the source list below, please also change the
 # OTcl script dependency list in Makefile.in
 #
+source ns-mipv6.tcl
 source ns-autoconf.tcl
 source ns-address.tcl
 source ns-node.tcl
 source ns-rtmodule.tcl
 source ns-hiernode.tcl
@@ -241,10 +242,11 @@
 	$self instvar useasim_
 	$self instvar slinks_
 	$self instvar nconn_
 	$self instvar sflows_
 	$self instvar nsflows_
+ 	$self instvar nodefactory_
 		
 	set slinks_(0:0) 0
 	set nconn_ 0
 	set conn_ ""
 	# for short flows stuff
@@ -336,10 +338,11 @@
 #                  -movementTrace OFF
 # change wrt Mike's code
 #                  -eotTrace OFF
 #                  -diffusionFilter "GradientFilter/OnePhasePullFilter/GeoRoutingFilter/RmstFilter/SourceRouteFilter/LogFilter/TagFilter"
 
+Simulator set nodefactory_ Node
 
 Simulator instproc addressType  {val} { $self set addressType_  $val }
 Simulator instproc adhocRouting  {val} { $self set routingAgent_  $val }
 Simulator instproc llType  {val} { $self set llType_  $val }
 Simulator instproc macType  {val} { $self set macType_  $val }
@@ -433,10 +436,23 @@
 		}
 		if { $val == "Base" && $wiredRouting_ == "OFF" } {
 			set val MIPMH
 		}
 	}
+	
+	#MOBIWAN Addition: start
+	if [$self mipv6?] {
+		# set val MIPv6
+		if { [info exists wiredRouting_] && $wiredRouting_ == "ON" } {
+			set val BS
+		}
+		if { [info exists wiredRouting_] && $wiredRouting_ == "OFF" } {
+			set val MN
+		}
+	}
+	#MOBIWAN Addition: stop
+	
 	return $val
 }
 
 Simulator instproc node-config args {
         # Object::init-vars{} is defined in ~tclcl/tcl-object.tcl.
@@ -499,11 +515,11 @@
  	# If both variables are specified, error!
  	if {[info exists channelType_] && [info exists channel_]} { 
 		error "Can't specify both channel and channelType, error!"
 	} elseif {[info exists channelType_] && ![info exists satNodeType_]} {
 		# Single channel, single interface
-		warn "Please use -channel as shown in tcl/ex/wireless-mitf.tcl"
+		warn "Please use -channel as shown in tcl/ex/wireless-mitf.tcl (except for MobiWAN simulations)"
 		if {![info exists chan]} {
 			set chan [new $channelType_]
 		}
  	} elseif {[info exists channel_]} {
 		# Multiple channel, multiple interfaces
@@ -528,10 +544,11 @@
 
 # Default behavior is changed: consider nam as not initialized if 
 # no shape OR color parameter is given
 Simulator instproc node args {
 	$self instvar Node_ routingAgent_ wiredRouting_ satNodeType_
+	$self instvar MNode_
         if { [Simulator info vars EnableMcast_] != "" } {
                 warn "Flag variable Simulator::EnableMcast_ discontinued.\n\t\
                       Use multicast methods as:\n\t\t\
                         % set ns \[new Simulator -multicast on]\n\t\t\
                         % \$ns multicast"
@@ -563,24 +580,31 @@
 		# for base node
 		if {[info exists wiredRouting_] && $wiredRouting_ == "ON"} {
 			set Node_([$node id]) $node
 			#simulator's nodelist in C++ space
 			$self add-node $node [$node id] 
+		} else {
+			#MOBIWAN Addition: Mobile nodes held in MNode_
+			set MNode_([$node id]) $node
+			#simulator's nodelist in C++ space
+			$self add-node $node [$node id] 
 		}
+		
 		return $node
 	}
 	
 
 	# Enable-mcast is now done automatically inside Node::init{}
 	# 
 	# XXX node_factory_ is deprecated, HOWEVER, since it's still used by
 	# mobile IP, algorithmic routing, manual routing, and backward 
 	# compability tests of hierarchical routing, we should keep it around
 	# before all related code are wiped out.
-	set node [eval new [Simulator set node_factory_] $args]
-	set Node_([$node id]) $node
 	
+	#set node [eval new [Simulator set node_factory_] $args]
+	set node [new Node $args]
+	set Node_([$node id]) $node
 	#add to simulator's nodelist in C++ space
 	$self add-node $node [$node id] 
 
 	#set the nodeid in c++ Node - ratul
 	$node nodeid [$node id]
@@ -619,10 +643,13 @@
     	}
         if {$rtAgentFunction_ != ""} {
 		set ragent [$self $rtAgentFunction_ $node]
 	} else {
 		switch -exact $routingAgent_ {
+		    Network {
+			    set ragent [$self create-network-agent $node]
+		    }
 		    DSDV {
 			    set ragent [$self create-dsdv-agent $node]
 		    }
 		    DSR {
 			    $self at 0.0 "$node start-dsr"
@@ -666,10 +693,14 @@
 			    exit
 		    }
 		}
 	}
 
+ 	if { [$self mipv6? ] } {
+ 		[$node set classifier_hier_] defaulttarget $ragent
+ 	}
+
 	# errProc_ and FECProc_ are an option unlike other 
         # parameters for node interface
 	if ![info exist inerrProc_] {
 		set inerrProc_ ""
 	}
@@ -678,16 +709,46 @@
 	}
 	if ![info exist FECProc_] {
 		set FECProc_ ""
 	}
 
+	# Add main node interface
 	
+	#MOBIWAN Addition: start
+	if [$self mipv6?] {
+		$self instvar iface_
+		#puts "Simulator::create-wireless-node: interface = $iface_"
+		if { [info exist iface_] && $iface_ == "LIGHT" } {
+			# XXX: For Testing - We don't use the full network stack
+			# XXX: Basically, we want to avoid a bug due to MAC when the
+			# XXX mobile node switches channel.
+			$node add-interface-light $chan $propInstance_ $llType_ $macType_ \
+			    $ifqType_ $ifqlen_ $phyType_ $antType_ $topoInstance_ \
+			    $inerrProc_ $outerrProc_ $FECProc_
+		} elseif { [info exist iface_] && [[Simulator instance] get-nodetype] == "MN" && $iface_ == "DUAL" } {
+			# MN with 2 interfaces.
+			# For inter-site mobility
+			$node add-interface $chan $propInstance_ $llType_ $macType_ \
+			    $ifqType_ $ifqlen_ $phyType_ $antType_ $topoInstance_ \
+			    $inerrProc_ $outerrProc_ $FECProc_
+			set nulchan [set_null_channel]
+			$node add-interface $nulchan $propInstance_ $llType_ $macType_ \
+			    $ifqType_ $ifqlen_ $phyType_ $antType_ $topoInstance_ \
+			    $inerrProc_ $outerrProc_ $FECProc_
+		} else {
+			# We use the full network stack
+			$node add-interface $chan $propInstance_ $llType_ $macType_ \
+			    $ifqType_ $ifqlen_ $phyType_ $antType_ $topoInstance_ \
+			    $inerrProc_ $outerrProc_ $FECProc_
+	#MOBIWAN Addition: stop
+		}
 
-	# Add main node interface
+	} else {
 	$node add-interface $chan $propInstance_ $llType_ $macType_ \
 	    $ifqType_ $ifqlen_ $phyType_ $antType_ $topoInstance_ \
 			$inerrProc_ $outerrProc_ $FECProc_
+	}
 	# Attach agent
 	if {$routingAgent_ != "DSR"} {
 		$node attach $ragent [Node set rtagent_port_]
 	}
 	if {$routingAgent_ == "DIFFUSION/RATE" ||
@@ -1721,12 +1782,19 @@
 Simulator instproc get-number-of-nodes {} {
 	return  [$self array size Node_]
 }
 
 Simulator instproc get-node-by-id id {
-	$self instvar Node_
+	$self instvar Node_ MNode_
+	
+	#MOBIWAN Addition: Start
+	if [info exists Node_($id)] {
 	return $Node_($id)
+        } else {
+                return  $MNode_($id)
+        }
+	#MOBIWAN Addition: Stop
 }
 
 # Given an node's address, Return the node-id
 Simulator instproc get-node-id-by-addr address {
 	$self instvar Node_
@@ -2258,5 +2326,7 @@
 	foreach i $lagent {
 		$i stop
 	}
 }
     
+
+source ns-local-lib.tcl
diff -urNU5 ns-2.33/tcl/lib/ns-local-lib.tcl ns-2.33-mobiwan/tcl/lib/ns-local-lib.tcl
--- ns-2.33/tcl/lib/ns-local-lib.tcl	1970-01-01 10:00:00.000000000 +1000
+++ ns-2.33-mobiwan/tcl/lib/ns-local-lib.tcl	2008-05-06 14:40:09.000000000 +1000
@@ -0,0 +1,14 @@
+# Mobiwan needs the following TCL extensions:
+# Source these files from the ns-lib.tcl file
+source ns-mipv6.tcl
+source ns-topoman.tcl
+source ns-mcast.tcl
+source ns-ping.tcl
+source proc-mipv6-config.tcl
+source proc-mobi-global.tcl
+source proc-tools.tcl
+source proc-mobi-config.tcl
+source proc-ping.tcl
+source proc-topo.tcl
+source proc-display.tcl
+
diff -urNU5 ns-2.33/tcl/lib/ns-mcast.tcl ns-2.33-mobiwan/tcl/lib/ns-mcast.tcl
--- ns-2.33/tcl/lib/ns-mcast.tcl	1970-01-01 10:00:00.000000000 +1000
+++ ns-2.33-mobiwan/tcl/lib/ns-mcast.tcl	2008-05-06 14:40:09.000000000 +1000
@@ -0,0 +1,135 @@
+# ############################################################################
+# This code was developed by Thierry Ernst (1998-2001)
+# MOTOROLA Labs Paris FRANCE - INRIA Rhone-Alpes Grenoble (PLANETE) FRANCE 
+# NS-2.1b6 enhancements for Wide-Area mobility simulations
+# ############################################################################
+
+# ############################################################################
+# Modifications to allow Mobile Nodes to support Multicast 
+# Tested with CtrMcast only
+# ############################################################################
+
+# ############################################################################
+# Existing proc that I need to modify from file /tcl/ctr-mcast/CtrMcast.tcl:
+# ############################################################################
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# CtrMcastComp instproc set_c_rp args 
+# To allow a mobile node to join a CBT mcast protocol
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+CtrMcastComp instproc set_c_rp args {
+        $self instvar ns_
+
+        foreach n [$ns_ ww-nodes] {
+                set arbiter [$n getArbiter]
+                #NS creates a virtual node per LAN.  This node does
+                #not have any the multicast features set.
+                if {$arbiter != ""} {
+                        set ctrmcast [$arbiter getType "CtrMcast"]
+                        $ctrmcast instvar c_rp_
+                        $ctrmcast unset_c_rp
+                }
+        }
+
+        foreach node $args {
+                set arbiter [$node getArbiter]
+                set ctrmcast [$arbiter getType "CtrMcast"]
+                $ctrmcast set_c_rp
+        }
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# CtrMcast instproc handle-cache-miss { srcID group iface } 
+# To allow a mobile node to join a CBT mcast protocol
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+CtrMcast instproc handle-cache-miss { srcID group iface } {
+        $self instvar ns_ agent_ node_
+        $self instvar defaultTree_
+
+        if { [$agent_ treetype? $group] == "" } {
+                $agent_ treetype $group $defaultTree_
+                #$agent_ add-new-member $group $node_
+         }
+        if { [$node_ id] == $srcID } {
+                # XXX Begin Enhancement
+                if [$ns_ is-mobile? [$node_ id]] {
+                   #set bs [$ns_ get-node-by-id [$node_ set bs_]]
+                   set bs [$ns_ get-node-by-addr [$node_ get-bs]]
+                   set RP [[[$bs getArbiter] getType "CtrMcast"] get_rp $group]
+                } else {
+                   set RP [$self get_rp $group]
+                }
+                # set RP [$self get_rp $group]
+                # XXX End Enhancement    
+                if {[$agent_ treetype? $group] == "RPT" && $srcID != [$RP id]} {
+                        set encapagent [new Agent/Encapsulator]
+                        $ns_ attach-agent $node_ $encapagent
+
+                        set ctrmcast [[$RP getArbiter] getType "CtrMcast"]
+                        $ns_ connect $encapagent [$ctrmcast set decapagent_]
+
+                        ### create (S,G,iif=-1) entry
+                        $node_ add-mfc-reg $srcID $group -1 $encapagent
+                }
+
+                if [$agent_ new-source? $group $node_] {
+                        $agent_ compute-tree $node_ $group
+                }
+        } elseif [SessionSim set MixMode_] {
+            set srcnode [$ns_ get-node-by-id $srcID]
+            if [$agent_ new-source? $group $srcnode] {
+                $agent_ compute-tree $srcnode $group
+            }
+        }
+        return 1 ;#call again
+}
+
+# ############################################################################
+# New procs
+# ############################################################################
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# About same procedure as Node instproc enable-mcast
+# but also allow hierarchical addressing at the same time
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Node/MobileNode instproc enable-mcast sim {
+        $self instvar classifiers_ multiclassifier_ ns_ switch_ mcastproto_
+        $self set ns_ $sim
+
+        $self set switch_ [new Classifier/Addr]
+        #
+        # set up switch to route unicast packet to slot 0 and
+        # multicast packets to slot 1
+        #
+
+        [$self set switch_] set mask_ [AddrParams set McastMask_]
+        [$self set switch_] set shift_ [AddrParams set McastShift_]
+
+        #
+        # create a classifier for multicast routing
+        #
+        $self set multiclassifier_ [new Classifier/Multicast/Replicator]
+        [$self set multiclassifier_] set node_ $self
+
+        $self set mrtObject_ [new mrtObject $self]
+
+        $switch_ install 0 $classifiers_(1)
+        $switch_ install 1 $multiclassifier_
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# This proc enable LBMcast or traditional multicast if relevant 
+# flag is set
+# XXX: cannot use both types simultaneously
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Node instproc test-mcast {} { 
+   $self instvar classifiers_
+    $self instvar ns_
+    if ![info exist ns_] {
+        set ns_ [Simulator instance]
+    }
+    if [$ns_ multicast?] {
+                $self enable-mcast $ns_
+    }
+    if [$ns_ lbmcast?] {
+                $self enable-lbmcast 
+    }
+}
diff -urNU5 ns-2.33/tcl/lib/ns-mipv6.tcl ns-2.33-mobiwan/tcl/lib/ns-mipv6.tcl
--- ns-2.33/tcl/lib/ns-mipv6.tcl	1970-01-01 10:00:00.000000000 +1000
+++ ns-2.33-mobiwan/tcl/lib/ns-mipv6.tcl	2008-05-06 14:40:09.000000000 +1000
@@ -0,0 +1,696 @@
+#
+# This software comprises contributed code made by Motorola, as a 
+# Contributor, to Network Simulator NS-2 software provided by the 
+# Regents of the University of California.
+# (Copyright; Regents of the University of California, 1994)
+# The contributed code was made as a result of a partnership between 
+# Motorola and INRIA Rhone-Alpes. 
+#
+# Copyright in the contributed code belongs to Motorola Inc. 2001
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+# ALL ADVERTISING MATERIALS MENTIONING FEATURES OR USE OF THIS SOFTWARE MUST 
+# DISPLAY AN ACKNOWLEDGEMENT TO THE COPYRIGHT OWNERS. 
+# ANY REDISTRIBUTION OF THIS SOFTWARE MUST CONTAIN THE ABOVE COPYRIGHT NOTICES, 
+# CONDITIONS AND DISCLAIMER.
+#
+#
+# ############################################################################
+# This code was developed by Thierry Ernst (1998-2001)
+# MOTOROLA Labs Paris FRANCE - INRIA Rhone-Alpes Grenoble (PLANETE) FRANCE 
+# NS-2.1b6 enhancements for Wide-Area mobility simulations
+# ############################################################################
+#
+# Modified for Mobiwan in ns-2.26 by WMC(mobiwan@ti-wmc.nl) -11/04
+#
+###############################################################################
+
+
+#Class Agent/MIPv6 -superclass Agent
+#Class Agent/MN -superclass Agent/MIPv6
+#Class Agent/MIPv6/BS -superclass Agent/MIPv6
+#Class Agent/CN -superclass Agent/MIPv6
+
+
+# ############################################################################
+# Defaults settings
+# ############################################################################
+Simulator set MIPv6_PORT	0	
+Simulator set DECAP_PORT	1	
+Simulator set RT_HDR_PORT	2
+
+Agent/MIPv6 set print_info_	0	;# output display
+Agent/MIPv6/MN set print_info_  0	;# output display
+Agent/MIPv6/BS set print_info_	0	;# output display
+Agent/MIPv6/CN set print_info_	0	;# output display
+
+Agent/MIPv6/BS set ad_lifetime_   	1	;# Lifetime of Router Advertisement
+Agent/MIPv6/MN set reg_lifetime_	10	;# BU Lifetime	
+Agent/MIPv6/MN set max_rate_		1 	;# BU interval when new CoA
+Agent/MIPv6/MN set slow_rate_		10	;# BU interval for refreshment 
+Agent/MIPv6/MN set rt_opti_		1	; # 1 if routing optimization ON 
+Agent/MIPv6/MN set bs_forwarding_	1	; # 1 if forwarding from previous BS 
+
+Agent/Network/NetworkBS set dport_              0
+Agent/Network/NetworkBS set print_info_ 0       ;# output display
+
+Agent/Network/NetworkMN set dport_              0
+Agent/Network/NetworkMN set print_info_ 0       ;# output display
+
+# ##########################################################################
+# General procedures to configure Mobile Nodes 
+# ##########################################################################
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Why this proc didn't exist ? this was not a hard work to write it !)
+# Class HierNode and node_factory will not be longer supported
+# from ns-2.1b7. Then, we want to get rid of this, but ...
+# 1. Simulator instproc set-hieraddress uses node_factory_ = HierNode
+# 2. proc entry-NewHier is missing
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Node instproc entry-NewHier {} {
+
+    return [$self entry-NewBase]
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# We need get-node-by-** to return the Mobile Node
+# but MNs id are not recorded in array Node_ as wired nodes
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Simulator instproc is-mobile? id {
+    $self instvar MNode_
+    if [info exists MNode_($id)] {
+	return 1
+    }
+    return 0
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# We need get-node-by-** to return the Mobile Node
+# List of ALL nodes, Wired, Wired/Wireless and Wireless
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Simulator instproc ww-nodes {} {
+    $self instvar Node_ MNode_
+    set nodes ""
+    foreach n [array names Node_] {
+	lappend nodes $Node_($n)
+    }
+    foreach n [array names MNode_] {
+	lappend nodes $MNode_($n)
+    }
+    set nodes
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Is this particular node LBM-enabled ?
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Node instproc lbmcast? {} {
+    $self instvar lbmcast_
+    if { ![info exists lbmcast_] } {
+	return 0
+    }
+    return $lbmcast_
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Is Simulator LBM-enabled ?
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Simulator instproc lbmcast? {} {
+    $self instvar lbmcast_
+    if { ![info exists lbmcast_] } {
+	return 0
+    }
+    return $lbmcast_
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Needed by Mobile IPv6 (particularly MN) to decapsulated packtes
+# Based on Node/MobileNode instproc attach-decap
+# o Currently, only MN needs a decapsulator
+# (XXX: This may be wrong if we use HMIP)
+# o All agent including MIPDecapsulator's default target is
+# MIPv6 Agent 
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Node/MobileNode instproc attach-decapsulator {} {
+    $self instvar decap_ dmux_ agents_ regagent_
+    
+    set decap_ [new Classifier/Addr/MIPDecapsulator]
+    lappend agents_ $decap_
+    
+    # Do I need this ???
+    # set mask 0x7fffffff
+    # set shift 0
+    # if {[expr [llength $agents_] - 1] > $mask} {
+    #    error "\# of agents attached to node $self exceeds port-field length of $m ask bits\n"
+    # }
+    
+    $dmux_ install [Simulator set DECAP_PORT] $decap_
+    $decap_ defaulttarget  [$self entry]
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Depending on option, this proc allow MN with one or two interfaces
+# The DUAL one is used for global mobility
+# If ALL: we use the standard Node/Mobile node stack  
+# If DUAL: just have two MAC / LL / IFq - NetworkMN Agent points to the one
+# currently in use.
+# XXXX If LIGHT: We don't need MAC / LL / ARP / etc.  But we need Phy.
+# XXX We remove the full network interface stack in oder to avoid a 
+# XXX persistent bug when we change from one channel to another.
+# XXX Bug is due to MAC because CTS (Clear to Send) are sent by the
+# XXX MN to the new channel though it was meant to the previous one
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Simulator instproc net-iface-type {val} {
+ $self instvar iface_
+
+   if { $val == "LIGHT" } {
+   # XXX We don't need this anymore - to be removed 
+      $self set iface_ LIGHT 
+   } elseif { $val == "DUAL" } {
+      $self set iface_ DUAL 
+   } else {
+      $self set iface_ ALL 
+   } 
+}
+
+# ##########################################################################
+# Routing Header Extensions
+# ##########################################################################
+SrcRouting set port_ [Simulator set RT_HDR_PORT]
+SrcRouting set addr_ 0
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Return the care-of address corresponding to the home address
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+SrcRouting instproc lookup-binding-cache mhaddr {
+    $self instvar node_
+    return [[$node_ set regagent_] set TunnelExit_($mhaddr)]
+}
+
+
+# ##########################################################################
+# Mobile IPv6 nodes configuration 
+# ##########################################################################
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Needed by node-config if mipv6 argument is used. 
+# If set, means we are using Mobile IPv6 Agent, and that we may
+# set encap and decap. 
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Simulator instproc mipv6 {val} {
+    $self instvar mipv6_
+    if { $val == "ON" } {
+	$self set mipv6_ 1 
+    } else {
+	$self set mipv6_ 0
+    } 
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Simulator instproc mipagent {val} {
+    $self instvar mipagent_ 
+    set mipagent_ $val
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Is simulator mipv6-enabled ? 
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Simulator instproc mipv6? {} {
+    $self instvar mipv6_
+    if { ![info exists mipv6_] } {
+	return 0 
+    }
+    return $mipv6_ 
+}
+
+# ##########################################################################
+# Node BS
+# ##########################################################################
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Base Stations and HA are able to encapsulate
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Node/MobileNode instproc makemip-NewBS {} {
+    
+    $self instvar regagent_ encap_ agents_ address_ dmux_ id_ classifier_hier_
+    $self instvar bcache_classifier_
+    set mipagent_ [[Simulator instance] set mipagent_]
+    
+    $self test-mcast
+    
+    set bcache_classifier_ [new Classifier/Hash/Dest 8]
+    $bcache_classifier_ set mask_ 0xffffffff
+    $bcache_classifier_ set shift_ 0
+    
+    $self insert-entry [$self get-module Hier] $bcache_classifier_ 0
+    $bcache_classifier_ defaulttarget $classifier_hier_
+    
+    if { $dmux_ == "" } {
+	set dmux_ [new Classifier/Port/Reserve]
+	$dmux_ set mask_ 0x7fffffff
+	$dmux_ set shift_ 0
+	
+	if [Simulator set EnableHierRt_] {  
+	    $classifier_hier_ install $address_ $dmux_
+	    #$self add-hroute $address_ $dmux_
+	} else {
+	    $self add-route $address_ $dmux_
+	}
+    } 
+    $self attach-redirect
+    set regagent_ [new Agent/MIPv6/$mipagent_ $self]
+    $self attach $regagent_ [Simulator set MIPv6_PORT]
+
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Node instproc set-node-addressBS { args } {
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Node instproc mk-default-classifierBS {} {
+    $self mk-default-classifierBase
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Node instproc entry-NewBS {} {
+    return [$self entry-NewBase]
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Node instproc install-defaulttarget-NewBS {rcvT} {
+    $self install-defaulttarget-NewBase $rcvT
+}    
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Node instproc do-resetBS {} {
+    $self do-resetBase
+}
+
+# ##########################################################################
+# Node MN
+# ##########################################################################
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# MN is able to decapsulate (encap not necessarily needed) 
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Node/MobileNode instproc makemip-NewMN {} {
+   
+    $self instvar regagent_ decap_ dmux_ address_ classifier_hier_ 
+    $self instvar bcache_classifier_
+    
+    set mipagent_ [[Simulator instance] set mipagent_]
+
+    $self test-mcast
+
+    set bcache_classifier_ [new Classifier/Hash/Dest 8]
+    $bcache_classifier_ set mask_ 0xffffffff
+    $bcache_classifier_ set shift_ 0
+    
+    $self insert-entry [$self get-module Hier] $bcache_classifier_ 0
+    $bcache_classifier_ defaulttarget $classifier_hier_    
+    
+    if { $dmux_ == "" } {
+        set dmux_ [new Classifier/Port/Reserve]
+        $dmux_ set mask_ 0x7fffffff
+        $dmux_ set shift_ 0
+        
+        if [Simulator set EnableHierRt_] {  
+	    $classifier_hier_ install $address_ $dmux_
+            #$self add-hroute $address_ $dmux_
+        } else {
+            $self add-route $address_ $dmux_
+        }
+    } 
+    $self attach-redirect
+    
+    set regagent_ [new Agent/MIPv6/$mipagent_ $self]
+    $self attach $regagent_ [Simulator set MIPv6_PORT]
+    $regagent_ node $self
+
+    # $self attach-decap
+    $self attach-decapsulator
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Node instproc set-node-addressMN { args } {
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Node instproc mk-default-classifierMN {} {
+    $self mk-default-classifierBase
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Node instproc entry-NewMN {} {
+    return [$self entry-NewBase]
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Node instproc install-defaulttarget-NewMN {rcvT} {
+    $self install-defaulttarget-NewBase $rcvT
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Node instproc do-resetMN {} {
+    $self do-resetBase
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Set the home agent of the mobile node
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Node/MobileNode instproc set-ha { ha_addr } {
+    $self instvar regagent_ ha_
+    $self set ha_ [[Simulator instance] get-node-by-addr $ha_addr]
+    $regagent_ set-ha [AddrParams set-hieraddr $ha_addr]
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Return the address of the Home Agent of the mobile node
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Node/MobileNode instproc get-ha-addr {} {
+    $self instvar regagent_ ha_
+    return [[$self set ha_] node-addr]
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Return the address of the Home Agent of the mobile node
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Node/MobileNode instproc get-ha {} {
+    $self instvar regagent_ ha_
+    return [$self set ha_]
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Add a new correspondent node to which a BU should be sent
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Node/MobileNode instproc add-cn { cn_addr } {
+    $self instvar regagent_
+    $regagent_ add-cn [AddrParams set-hieraddr $cn_addr]
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Node/MobileNode instproc remove-cn { cn_addr } {
+    $self instvar regagent_
+    $regagent_ remove-cn [AddrParams set-hieraddr $cn_addr]
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Node/MobileNode instproc add-group { group } {
+    $self instvar regagent_
+    $regagent_ add-group $group
+}
+
+# ##########################################################################
+# Other IPv6 Nodes 
+# ##########################################################################
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Nodes created after node-config is called with arg mipv6 
+# are mobile IPv6-enable and able to encapsulate 
+# XXX: makemip-NewBS and MN should call makemip-NewHier directly
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Node instproc makemip-NewHier {} {
+    
+    $self instvar regagent_ encap_ agents_ address_ dmux_ id_ classifier_hier_
+    $self instvar bcache_classifier_
+    set mipagent_ [[Simulator instance] set mipagent_]
+    $self test-mcast
+    
+    set bcache_classifier_ [new Classifier/Hash/Dest 8]
+    $bcache_classifier_ set mask_ 0xffffffff
+    $bcache_classifier_ set shift_ 0
+    
+    $self insert-entry [$self get-module Hier] $bcache_classifier_ 0
+    $bcache_classifier_ defaulttarget $classifier_hier_
+    
+    if { $dmux_ == "" } {
+	set dmux_ [new Classifier/Port/Reserve]
+	$dmux_ set mask_ 0x7fffffff
+	$dmux_ set shift_ 0
+
+	if [Simulator set EnableHierRt_] {
+	    $classifier_hier_ install $address_ $dmux_
+	    #$self add-hroute $address_ $dmux_
+	} else {
+	    $self add-route $address_ $dmux_
+	}
+    }
+    $self attach-redirect
+    set regagent_ [new Agent/MIPv6/$mipagent_ $self]
+    $self attach $regagent_ [Simulator set MIPv6_PORT]
+    
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# This procedure allows the node to redirect packets.
+# (Source routing or tunneling)
+# NodeMobileNode and Node both call this proc. 
+# XXX: originally Node instproc attach-encap
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Node instproc attach-redirect {} {
+    
+    $self instvar encap_ address_ classifiers_ bcache_classifier_
+    $self instvar src_routing_ src_classifier_ classifier_ classifier_hier_
+    
+    
+    if [Simulator set EnableHierRt_] {
+        set nodeaddr [AddrParams addr2id $address_]
+    } else {
+        set nodeaddr [expr ( $address_ &                        \
+				 [AddrParams set NodeMask 1] ) <<      \
+			  [AddrParams set NodeShift 1]]
+    }
+    
+    # For Routing header insertion
+    set src_routing_ [new SrcRouting]
+    $src_routing_ set port_ [Simulator set RT_HDR_PORT] 
+    $src_routing_ set node_ $self
+    $self attach $src_routing_ [Simulator set RT_HDR_PORT]
+    $src_routing_ node $self
+    
+    # For Encapsulation
+    set encap_ [new MIPEncapsulator]
+    $encap_ set addr_ $nodeaddr
+    $encap_ set port_ 1
+    #$encap_ target $classifiers_(1)
+    $encap_ target $classifier_hier_ 
+    $encap_ set node_ $self
+    
+    # To decide (in case we have an entry in the binding cache)
+    # if packet should be sent using a routing header 
+    # (source = local node) or using tunneling 
+    set src_classifier_ [new Classifier/Hash/Src 2]
+    $src_classifier_ set mask_ 0xffffffff
+    $src_classifier_ set shift_ 0 
+    $src_classifier_ defaulttarget $encap_
+    $src_classifier_ install $nodeaddr $src_routing_
+    
+    
+    set ns_ [Simulator instance]
+    if { [$self lbmcast?] || [$ns_ multicast?] } {
+        $self instvar switch_
+
+    	# Link switch to bcache_classifier instead of classifier_
+    	$switch_ install 0 $bcache_classifier_
+    }
+
+}
+
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Agent/MIPv6 instproc init args {
+    eval $self next $args
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Agent/MIPv6 instproc getid { } {
+    $self instvar node_  
+    return [$node_ id]
+}
+
+# ##########################################################################
+# Agent BS (Base Station and HA)
+# ##########################################################################
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Set Router Advertisement interval to some specified value
+# This also starts the emission of Router Advertisements 
+# RA may be stopped and restarted at anytime using start-beacon/
+# stop-beacon 
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Agent/MIPv6/BS instproc init args {
+    set args [eval $self init-vars $args]	
+    eval $self next $args
+    $self set-beacon-period 1.0; # default value
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Agent/MIPv6/BS instproc encap-route { mhaddr coa lifetime } {
+    $self instvar node_ TunnelExit_ RegTimer_
+    
+    set ns [Simulator instance]
+    set bcache [$node_ set bcache_classifier_]
+    set target [$node_ set src_classifier_]
+    
+    # Make slot points to src_classifier if packet ought to be redirected 
+    $bcache install $mhaddr $target
+    
+    set TunnelExit_($mhaddr) $coa
+    if { [info exists RegTimer_($mhaddr)] && $RegTimer_($mhaddr) != "" } {
+	$ns cancel $RegTimer_($mhaddr)
+    }
+    set RegTimer_($mhaddr) [$ns at [expr [$ns now] + $lifetime] \
+				"$self clear-reg $mhaddr"]
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Agent/MIPv6/BS instproc clear-reg mhaddr {
+    $self instvar node_ RegTimer_
+    
+    set bcache [$node_ set bcache_classifier_]
+    set target [$node_ set classifier_hier_]
+     
+    $bcache install $mhaddr $target 
+    
+    if { [info exists RegTimer_($mhaddr)] && $RegTimer_($mhaddr) != "" } {
+	[Simulator instance] cancel $RegTimer_($mhaddr)
+	set RegTimer_($mhaddr) ""
+    }
+}
+
+# ##########################################################################
+# Agent MN (Mobile Node)
+# ##########################################################################
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Agent/MIPv6/MN instproc init args {
+    
+    eval $self next $args
+
+    # Set beacon period and starts the beacon timer.
+    # Allow one beacon to be lost before deciding we have lost contact
+    $self check-beacon 2.3     ;# default value
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Return the careof address = prefix of base station + node id % 128.
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Agent/MIPv6/MN instproc get-coa { bs_addr } {
+    $self instvar node_
+    set prefix [get_subnet_prefix $bs_addr]
+    set suffix [expr [$node_ set id_] % 128]
+    return [AddrParams set-hieraddr $prefix.$suffix]
+}
+
+# ##########################################################################
+# Agent CN (Correspondent Node)
+# ##########################################################################
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Agent/MIPv6/CN instproc init args {	
+    eval $self next $args
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Agent/MIPv6/CN instproc encap-route { mhaddr coa lifetime } {
+    $self instvar node_ TunnelExit_ RegTimer_
+    
+    set ns [Simulator instance]
+    set bcache [$node_ set bcache_classifier_]
+    set target [$node_ set src_classifier_]
+    
+    # Make slot points to src_classifier if packet ought to be redirected 
+    $bcache install $mhaddr $target
+    
+    set TunnelExit_($mhaddr) $coa
+    if { [info exists RegTimer_($mhaddr)] && $RegTimer_($mhaddr) != "" } {
+        $ns cancel $RegTimer_($mhaddr)
+    }
+    set RegTimer_($mhaddr) [$ns at [expr [$ns now] + $lifetime] \
+				"$self clear-reg $mhaddr"]
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Clear Binding between MN's home address and MN's COA.
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Agent/MIPv6/CN instproc clear-reg mhaddr {
+    $self instvar node_ RegTimer_
+    
+    set bcache [$node_ set bcache_classifier_]
+    set target [$node_ set classifier_hier_]
+    
+    $bcache install $mhaddr $target
+    
+    if { [info exists RegTimer_($mhaddr)] && $RegTimer_($mhaddr) != "" } {
+        [Simulator instance] cancel $RegTimer_($mhaddr)
+        set RegTimer_($mhaddr) ""
+    }
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Method to remove an entry from the hier classifiers
+# Exactly same as Node/MobileNode instproc clear-hroute args
+# But did not exist until now.
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#Node instproc clear-hroute args
+#    $self instvar classifiers_
+#    set a [split $args]
+#    set l [llength $a]
+#    $classifiers_($l) clear [lindex $a [expr $l-1]]
+
+
+# ##########################################################################
+# Network agent that replaces Ad-hoc routing agent
+# Particularly needed by the MN:
+# - to forward packet to the Base Station by setting the next_hop field
+# - to monitor what are the active Correspondent Nodes 
+# XXX: Router Advertisement and Solicitations should also be processed
+# here, but still in the Mobile IPv6 agent until now.
+# ##########################################################################
+Simulator instproc create-network-agent { node } {
+    
+    set nodetype_ [$self get-nodetype]
+    if { $nodetype_ == "BS" } {
+    	set ragent [new Agent/Network/NetworkBS]
+    } else {
+	if { $nodetype_ == "MN" } {
+	    set ragent [new Agent/Network/NetworkMN]
+	    $ragent mip-agent [$node set regagent_]
+	    $ragent decap-port [Simulator set DECAP_PORT]
+	} else {
+	    puts "Wrong Routing Agent"
+	}
+    }
+    
+    ## setup address (supports hier-addr) for site agent
+    ## and mobilenode
+    set addr [$node node-addr]
+    $ragent addr $addr
+    $ragent node $node
+    
+    if [Simulator set mobile_ip_] {
+        $ragent port-dmux [$node set dmux_]
+    }
+    $node addr $addr
+    $node set ragent_ $ragent
+    
+    #delay till after add interface
+    #   $node attach $ragent 255
+    
+    # start-site is useless, unless we want to move Router Advertisement here
+    # $self at 0.0 "$ragent start-site"    ;# start 
+    
+    return $ragent
+}
+
+
+
diff -urNU5 ns-2.33/tcl/lib/ns-mobilenode.tcl ns-2.33-mobiwan/tcl/lib/ns-mobilenode.tcl
--- ns-2.33/tcl/lib/ns-mobilenode.tcl	2008-04-01 13:00:23.000000000 +1100
+++ ns-2.33-mobiwan/tcl/lib/ns-mobilenode.tcl	2008-05-06 14:40:09.000000000 +1000
@@ -253,14 +253,18 @@
 	set ns [Simulator instance]
 	set newapi [$ns imep-support]
 	set namfp [$ns get-nam-traceall]
 
 	set dmux_ [$self demux]
-	set classifier_ [$self entry]
 
 	# let the routing agent know about the port dmux
 	$agent port-dmux $dmux_
+	if [$ns mipv6?] {
+	     set classifier_ [$self set classifier_hier_]
+	} else {
+	set classifier_ [$self entry]
+	}
 
 	if { [Simulator set RouterTrace_] == "ON" } {
 		#
 		# Send Target
 		#
diff -urNU5 ns-2.33/tcl/lib/ns-node.tcl ns-2.33-mobiwan/tcl/lib/ns-node.tcl
--- ns-2.33/tcl/lib/ns-node.tcl	2008-04-01 13:00:23.000000000 +1100
+++ ns-2.33-mobiwan/tcl/lib/ns-node.tcl	2008-05-06 14:40:09.000000000 +1000
@@ -33,10 +33,12 @@
 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 # SUCH DAMAGE.
 #
 # @(#) $Header: /cvsroot/nsnam/ns-2/tcl/lib/ns-node.tcl,v 1.89 2001/11/06 06:16:21 tomh Exp $
 #
+# Originally modified for Mobiwan in ns-2.26 by WMC(mobiwan@ti-wmc.nl) -11/04
+#
 
 Node set nn_ 0
 Node proc getid {} {
 	set id [Node set nn_]
 	Node set nn_ [expr $id + 1]
@@ -61,15 +63,14 @@
 		set module_list_ [lreplace $module_list_ $pos $pos]
 	}
 }
 
 Node instproc init args {
-	eval $self next $args
-
+	#eval $self next $args
         $self instvar id_ agents_ dmux_ neighbor_ rtsize_ address_ \
 			nodetype_ multiPath_ ns_ rtnotif_ ptnotif_
-
+        eval $self next $args
 	set ns_ [Simulator instance]
 	set id_ [Node getid]
 	$self nodeid $id_	;# Propagate id_ into c++ space
 
 	if {[llength $args] != 0} {
@@ -85,11 +86,22 @@
         set rtsize_ 0
 	set ptnotif_ {}
 	set rtnotif_ {}
 	set nodetype_ [$ns_ get-nodetype]
 
+	if { [$ns_ mipv6? ] } {
+
+		#MOBIWAN Addition
+		$self set-node-address$nodetype_ $args
+
+		$self cmd addr $address_; # Propagate address_ into C++ space
+
+		$self mk-default-classifier$nodetype_
+		#MOBIWAN
+	} else {
 	$self mk-default-classifier
+	}	
 
 	# XXX Eventually these two should also be converted to modules
 	set multiPath_ [$class set multiPath_]
 }
 
@@ -174,10 +186,11 @@
 	$self instvar rtsize_
 	incr rtsize_ -1
 }
 
 Node instproc entry {} {
+	$self instvar classifier_
 	return [$self set classifier_]
 }
 
 # Place classifier $clsfr at the node entry point. 
 #
@@ -195,11 +208,11 @@
 #   to which the replaced classifier is linked.
 #
 # - To install at the entry something derived from Connector rather than 
 #   Classifier, you should specify $hook as "target". 
 Node instproc insert-entry { module clsfr {hook ""} } {
-	$self instvar classifier_ mod_assoc_ hook_assoc_
+	$self instvar classifier_ mod_assoc_ hook_assoc_ ns_
 	if { $hook != "" } {
 		# Build a classifier "chain" when specified
 		set hook_assoc_($clsfr) $classifier_
 		if { $hook == "target" } {
 			$clsfr target $classifier_
@@ -208,10 +221,13 @@
 		}
 	}
 	# Associate this module to the classifier, so if the classifier is
 	# removed later, we'll remove the module as well.
 	set mod_assoc_($clsfr) $module
+	if { [$ns_ mipv6? ] } {
+		$self set classifier_hier_ $classifier_
+	}
 	set classifier_ $clsfr
 }
 
 # We separate insert-entry from install-entry because we need a method to 
 # replace the current entry classifier and _remove_ routing functionality 
@@ -464,38 +480,59 @@
 # method. Since this method will be called during Node::init{}, when 
 # Node::attach{} is called dmux_ will already be present hence the following
 # default dmux_ construction will not be triggered.
 #
 Node instproc attach { agent { port "" } } {
-	$self instvar agents_ address_ dmux_ 
+	$self instvar agents_ address_ dmux_ classifier_
+        $self instvar classifiers_	
 	#
 	# Assign port number (i.e., this agent receives
 	# traffic addressed to this host and port)
 	#
 	lappend agents_ $agent
 	#
 	# Attach agents to this node (i.e., the classifier inside).
 	# We call the entry method on ourself to find the front door
 	# (e.g., for multicast the first object is not the unicast classifier)
 	#
+	
+	set mask [AddrParams set ALL_BITS_SET]
+	set shift 0
+	
 	# Also, stash the node in the agent and set the local addr of 
 	# this agent.
 	#
 	$agent set node_ $self
+	if [Simulator set EnableHierRt_] {
 	$agent set agent_addr_ [AddrParams addr2id $address_]
+	} else {
+		$agent set agent_addr_ [expr ($address_ & \
+						  [AddrParams set NodeMask 1]) \
+					    << [AddrParams set NodeShift 1]]
+	}
 	#
 	# If a port demuxer doesn't exist, create it.
 	#
 	if { $dmux_ == "" } {
 		# Use the default mask_ and port_ values
 		set dmux_ [new Classifier/Port]
+		$dmux_ set mask_ $mask
+		$dmux_ set shift_ $shift
 		# point the node's routing entry to itself
 		# at the port demuxer (if there is one)
+	    if [Simulator set EnableHierRt_] {
+		    ###TODO: Do wee need to set up the classifiers here too??
+		    #$self add-hroute $address_ $dmux_
+	    } else {
 		$self add-route $address_ $dmux_
 	}
+	}
 	if { $port == "" } {
-		set port [$dmux_ alloc-port [[Simulator instance] nullagent]]
+		#set port [$dmux_ alloc-port [[Simulator instance] nullagent]]
+		set ns_ [Simulator instance]
+		$ns_ instvar nullAgent_
+		set port [$self alloc-port $nullAgent_]
 	}
 	$agent set agent_port_ $port
 
 	$self add-target $agent $port
 }
@@ -509,10 +546,33 @@
 	foreach m [$self set ptnotif_] {
 		$m attach $agent $port
 	}
 }
 
+Node instproc add-target-New {agent port} {
+		
+   $self instvar dmux_
+   #
+   # Send Target
+   #
+   $agent target [$self entry]
+
+   #
+   # Recv Target
+   #
+   $dmux_ install $port $agent
+
+}
+
+Node instproc add-target-NewBase {agent port} {
+	$self add-target-NewMobile $agent $port
+}
+
+Node instproc add-target-NewHier {agent port} {
+	$self add-target-New $agent $port
+}
+
 # Detach an agent from a node.
 Node instproc detach { agent nullagent } {
 	$self instvar agents_ dmux_
 	#
 	# remove agent from list
@@ -535,10 +595,16 @@
 	}
 }
 
 # reset all agents attached to this node
 Node instproc reset {} {
+	$self instvar nodetype_
+	$self do-reset$nodetype_
+
+}
+# reset all agents attached to this node
+Node instproc do-reset {} {
 	$self instvar agents_
 	foreach a $agents_ {
 		$a reset
 	}
 	foreach m [$self list-modules] {
@@ -567,5 +633,893 @@
 
 Node instproc is-neighbor { node } {
 	$self instvar neighbor_
 	return [expr [lsearch $neighbor_ $node] != -1]
 }
+
+#######################################################
+#######################################################
+
+# MOBIWAN Extensions to ns2.26
+
+#######################################################
+#######################################################
+
+Node instproc set-node-address { args } {
+}
+
+Node instproc set-node-addressMIPBS { args } {
+}
+
+Node instproc set-node-addressMIPMH { args } {
+}
+
+Node instproc set-node-addressMobile { args } {
+    
+    $self instvar nifs_ arptable_
+    $self instvar netif_ mac_ ifq_ ll_
+    $self instvar X_ Y_ Z_
+
+    set X_ 0.0
+    set Y_ 0.0
+    set Z_ 0.0
+    set arptable_ ""                ;# no ARP table yet
+
+    set nifs_	0		;# number of network interfaces
+
+}
+
+Node instproc set-node-addressHier {args} {
+    $self instvar address_
+
+    set address_ $args
+}
+
+Node instproc set-node-addressBase {args} {
+}
+
+Node instproc mk-default-classifierMIPMH {} {
+    $self mk-default-classifierBase
+}
+
+Node instproc mk-default-classifierMIPBS {} {
+    $self mk-default-classifierBase
+}
+
+Node instproc mk-default-classifierBase {} {
+    $self mk-default-classifierHier
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# TOPOMAN modifications needed for Mobile IPv6
+# This allows to set up Mobile IPv6 capabilities in the new Node
+# Call proc that set MIPv6 agent if mipv6 flag is set
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Node instproc mk-default-classifierHier {} {
+
+	$self instvar np_ id_ classifiers_ agents_ dmux_ neighbor_ address_
+	$self instvar module_list_
+
+        # At minimum we should enable base module
+        foreach modname [Node set module_list_] {
+		$self register-module [new RtModule/$modname]
+        } 
+	
+	set ns [Simulator instance]
+	if [$ns mipv6?] {
+		if { [$self set nodetype_] == "Hier" } {
+			$self makemip-NewHier
+		}
+	}
+}
+
+
+# mobileNode
+
+Node instproc mk-default-classifierMobile {} {
+	$self mk-default-classifier
+}
+
+## splitting up address str: used by other non-hier classes
+Node instproc split-addrstr addrstr {
+	set L [split $addrstr .]
+	return $L
+}
+
+#XXX: Obsolete??
+#Node instproc add-neighbor p {
+#	$self instvar neighbor_
+#	lappend neighbor_ $p
+#}
+
+Node instproc entry-NewHier {} {
+	return [$self entry-NewBase]
+}
+
+Node instproc entry-NewMIPBS {} {
+	return [$self entry-NewBase]
+}
+
+Node instproc entry-NewMIPMH {} {
+	return [$self entry-NewBase]
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# MOBIWAN modifications
+# Modification needed by Mobile IPv6
+# Modifies the existing Node instproc entry-NewBase:
+# o Entry point of node is Switch if node is mcast enabled 
+# o Entry point of node is mn_classifier if not mcast enabled 
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Node instproc entry-NewBase {} {
+	$self instvar ns_
+	
+	if ![info exist ns_] {
+		set ns_ [Simulator instance]
+	}
+	if { [$self lbmcast?] || [$ns_ multicast?] } {
+		$self instvar switch_
+		return $switch_
+	}
+	if { [$ns_ mipv6? ] } {
+		$self instvar bcache_classifier_
+		return $bcache_classifier_
+	}
+	$self instvar classifiers_
+	return $classifiers_(1)
+}
+
+
+Node instproc entry-New {} {
+
+	if [info exists router_supp_] {
+		return $router_supp_
+	}
+	if ![info exist ns_] {
+		set ns_ [Simulator instance]
+	}
+	if [$ns_ multicast?] {
+		$self instvar switch_
+		return $switch_
+	}
+	$self instvar classifier_
+	return $classifier_
+}
+
+Node instproc entry-NewMobile {} {
+	return [$self entry-New]
+}
+
+Node instproc get-nam-traceall {args} {
+	
+	$self instvar namtraceFile_
+	set file [lindex $args 0]
+	set namtraceFile_ $file
+	
+}
+
+
+Node instproc do-resetMobile {} {
+    	$self instvar arptable_ nifs_
+	$self instvar netif_ mac_ ifq_ ll_
+	$self instvar imep_
+	
+        for {set i 0} {$i < $nifs_} {incr i} {
+		$netif_($i) reset
+		$mac_($i) reset
+		$ll_($i) reset
+		$ifq_($i) reset
+		if { [info exists opt(imep)] && $opt(imep) == "ON" } { $imep_($i) reset }
+		
+	}
+	
+	if { $arptable_ != "" } {
+		$arptable_ reset 
+	}
+	
+}
+
+Node instproc do-resetBase {} {
+	$self do-resetMobile
+}
+
+Node instproc do-resetHier {} {
+	$self do-reset
+}
+
+Node instproc attachInterfaces ifs {
+	$self instvar ifaces_
+	set ifaces_ $ifs
+	foreach ifc $ifaces_ {
+		$ifc setNode $self
+	}
+}
+
+Node instproc addInterface { iface } {
+	$self instvar ifaces_
+	lappend ifaces_ $iface
+	#	$iface setNode $self 
+}
+
+Node instproc createInterface { num } {
+	$self instvar ifaces_
+	set newInterface [new NetInterface]
+	if { $num < 0 } { return 0 }
+	$newInterface set-label $num
+	return 1
+}
+
+Node instproc getInterfaces {} {
+	$self instvar ifaces_
+	return $ifaces_
+}
+
+Node instproc getNode {} {  
+	return $self
+}
+
+
+#
+# helpers for PIM stuff
+#
+
+Node instproc get-vif {} {
+	$self instvar vif_ 
+	if [info exists vif_] { return $vif_ }
+	set vif_ [new NetInterface]
+	$self addInterface $vif_
+	return $vif_
+}
+
+# List of corresponding peer TCP hosts from this node, used in IntTcp
+
+Node instproc addCorresHost {addr cw mtu maxcw wndopt } {
+	$self instvar chaddrs_
+	
+	if { ![info exists chaddrs_($addr)] } {
+		set chost [new Agent/Chost $addr $cw $mtu $maxcw $wndopt]
+		set chaddrs_($addr) $chost
+	}
+	return $chaddrs_($addr)
+}
+
+Node instproc createTcpSession {dst} {
+	$self instvar tcpSession_
+	
+	if { ![info exists tcpSession_($dst)] } {
+		set tcpsession [new Agent/TCP/Session]
+		$self attach $tcpsession
+		$tcpsession set dst_ $dst
+		set tcpSession_($dst) $tcpsession
+	}
+	return $tcpSession_($dst)
+}
+
+Node instproc getTcpSession {dst} {
+	$self instvar tcpSession_
+	
+	if { [info exists tcpSession_($dst)] } {
+		return $tcpSession_($dst)
+	} else {
+		puts "In getTcpSession(): no session exists for destination [$dst set addr_]"
+		return ""
+	}
+}
+
+Node instproc existsTcpSession {dst} {
+	$self instvar tcpSession_
+	
+	if { [info exists tcpSession_($dst)] } {
+		return 1
+	} else {
+		return 0
+	}
+}
+
+#
+# Manual Routing Nodes:
+# like normal nodes, but with a hash classifier.
+#
+
+Class ManualRtNode -superclass Node
+
+ManualRtNode instproc mk-default-classifier {} {
+	$self instvar address_ classifier_ id_ dmux_
+	
+	# Note the very small hash size---
+	# you're supposed to resize it if you want more.
+	set classifier_ [new Classifier/Hash/Dest 2]
+
+	$classifier_ set mask_ [AddrParams set NodeMask 1]
+	$classifier_ set shift_ [AddrParams set NodeShift 1]
+	set address_ $id_
+	
+}
+
+ManualRtNode instproc add-route {dst_address target} {
+	$self instvar classifier_ 
+	set slot [$classifier_ installNext $target]
+	if {$dst_address == "default"} {
+		$classifier_ set default_ $slot
+	} else {
+		# don't encode the address here, set-hash bypasses that for us
+		set encoded_dst_address [expr $dst_address << [AddrParams set NodeShift 1]]
+		$classifier_ set-hash auto 0 $encoded_dst_address 0 $slot
+		# $classifier_ set-hash auto 0 $dst_address 0 $slot
+	}
+	# 	puts "ManualRtNode::add-route: $dst $target, classifier=$classifier_ slot=$slot"
+	#	puts "\t*slot=[$classifier_ slot $slot]"
+}
+
+ManualRtNode instproc add-route-to-adj-node args {
+	$self instvar classifier_ address_
+	
+	set dst ""
+	if {[lindex $args 0] == "-default"} {
+		set dst default
+		set args [lrange $args 1 end]
+	}
+	if {[llength $args] != 1} {
+		error "ManualRtNode::add-route-to-adj-node [-default] node"
+	}
+	set target_node $args
+	if {$dst == ""} {
+		set dst [$target_node set address_]
+	}
+	set ns [Simulator instance]
+	set link [$ns link $self $target_node]
+	set target [$link head]
+	# puts "ManualRtNode::add-route-to-adj-node: in $self for addr $dst to target $target"
+	return [$self add-route $dst $target]
+}
+
+
+
+
+#
+# Virtual Classifier Nodes:
+# like normal nodes, but with a virtual unicast classifier.
+#
+Class VirtualClassifierNode -superclass Node
+
+VirtualClassifierNode instproc mk-default-classifier {} {
+	$self instvar address_ classifier_ id_
+	
+	set classifier_ [new Classifier/Virtual]
+	$classifier_ set node_ $self
+
+	$classifier_ set mask_ [AddrParams set NodeMask 1]
+	$classifier_ set shift_ [AddrParams set NodeShift 1]
+	set address_ $id_
+	
+	$classifier_ nodeaddr $address_
+}
+
+VirtualClassifierNode instproc add-route { dst target } {
+}
+
+Classifier/Virtual instproc find dst {
+	$self instvar node_ ns_ routingTable_
+	
+	if ![info exist ns_] {
+		set ns_ [Simulator instance]
+	}
+	if {[$node_ id] == $dst} {
+		return [$node_ set dmux_]
+	} else {
+		return [[$ns_ link $node_ [$ns_ set Node_($dst)]] head]
+	}
+}
+
+Classifier/Virtual instproc install {dst target} {
+}
+
+#     
+# Broadcast Nodes:
+# accept limited broadcast packets
+#     
+
+Class Node/Broadcast -superclass Node
+
+Node/Broadcast instproc mk-default-classifier {} {
+        $self instvar address_ classifier_ id_ dmux_
+        set classifier_ [new Classifier/Hash/Dest/Bcast 32]
+	
+        $classifier_ set mask_ [AddrParams set NodeMask 1]
+        $classifier_ set shift_ [AddrParams set NodeShift 1]
+        set address_ $id_
+        
+	if { $dmux_ == "" } {
+                set dmux_ [new Classifier/Port/Reserve]
+		$dmux_ set mask_ [AddrParams set ALL_BITS_SET]
+                $dmux_ set shift_ 0
+		
+                if [Simulator set EnableHierRt_] {  
+                        $self add-hroute $address_ $dmux_
+                } else {
+                        $self add-route $address_ $dmux_
+                }
+        }
+        $classifier_ bcast-receiver $dmux_
+}
+
+# New node structure
+
+Node instproc add-target-NewMobile {agent port} {
+
+	#global opt
+	$self instvar dmux_ classifier_
+	$self instvar imep_ toraDebug_
+	
+	set ns_ [Simulator instance]
+	
+	set newapi [$ns_ imep-support]
+	$agent set sport_ $port
+	
+	#special processing for TORA/IMEP node
+	set toraonly [string first "TORA" [$agent info class]] 
+	
+	if {$toraonly != -1 } {
+		$agent if-queue [$self set ifq_(0)]    ;# ifq between LL and MAC
+		#
+		# XXX: The routing protocol and the IMEP agents needs handles
+		# to each other.
+		#
+		$agent imep-agent [$self set imep_(0)]
+		[$self set imep_(0)] rtagent $agent
+		
+	}
+	
+	
+	if { $port == 255 } {			# non-routing agents
+		
+		if { [Simulator set RouterTrace_] == "ON" } {
+			#
+			# Send Target
+			#
+			
+			if {$newapi != ""} {
+				set sndT [$ns_ mobility-trace Send "RTR" $self]
+			} else {
+				set sndT [cmu-trace Send "RTR" $self]
+			}
+			if [info exists namtraceFile_]  {
+				$sndT namattach $namtraceFile_
+			}
+			
+			if { $newapi == "ON" } {
+				$agent target $imep_(0)
+				$imep_(0) sendtarget $sndT
+				
+				# second tracer to see the actual
+				# types of tora packets before imep packs them
+				#if { [info exists opt(debug)] && $opt(debug) == "ON" } {
+				if { [info exists toraDebug_] && $toraDebug_ == "ON"} {
+					set sndT2 [$ns_ mobility-trace Send "TRP" $self]
+					$sndT2 target $imep_(0)
+					$agent target $sndT2
+				}
+			} else {  ;#  no IMEP
+				$agent target $sndT
+			}
+			
+			$sndT target [$self set ll_(0)]
+			#	    $agent target $sndT
+			
+			#
+			# Recv Target
+			#
+			
+			if {$newapi != ""} {
+				set rcvT [$ns_ mobility-trace Recv "RTR" $self]
+			} else {
+				set rcvT [cmu-trace Recv "RTR" $self]
+			}
+			if [info exists namtraceFile_]  {
+				$rcvT namattach $namtraceFile_
+			}
+			
+			if {$newapi == "ON" } {
+				#    puts "Hacked for tora20 runs!! No RTR revc trace"
+				[$self set ll_(0)] up-target $imep_(0)
+				$classifier_ defaulttarget $agent
+				
+				# need a second tracer to see the actual
+				# types of tora packets after imep unpacks them
+				#if { [info exists opt(debug)] && $opt(debug) == "ON" } {
+				# no need to support any hier node
+				
+				if {[info exists toraDebug_] && $toraDebug_ == "ON" } {
+					set rcvT2 [$ns_ mobility-trace Recv "TRP" $self]
+					$rcvT2 target $agent
+					[$self set classifier_] defaulttarget $rcvT2
+				}
+				
+			} else {
+				$rcvT target $agent
+				
+				$self install-defaulttarget $rcvT
+				$dmux_ install $port $rcvT
+			}
+
+			#	    $rcvT target $agent
+			#	    $classifier_ defaulttarget $rcvT
+			#	    $dmux_ install $port $rcvT
+			
+		} else {
+			#
+			# Send Target
+			#
+			$agent target [$self set ll_(0)]
+			
+			#
+			# Recv Target
+			#
+			
+			$self install-defaulttarget $agent
+			
+			#$classifier_ defaulttarget $agent
+			
+			$dmux_ install $port $agent
+		}
+		
+	} else {
+		if { [Simulator set AgentTrace_] == "ON" } {
+			#
+			# Send Target
+			#
+			
+			if {$newapi != ""} {
+				set sndT [$ns_ mobility-trace Send AGT $self]
+			} else {
+				set sndT [cmu-trace Send AGT $self]
+			}
+			
+			$sndT target [$self entry]
+			$agent target $sndT
+			
+			#
+			# Recv Target
+			#
+			if {$newapi != ""} {
+				set rcvT [$ns_ mobility-trace Recv AGT $self]
+			} else {
+				set rcvT [cmu-trace Recv AGT $self]
+			}
+			
+			$rcvT target $agent
+			$dmux_ install $port $rcvT
+			
+		} else {
+			#
+			# Send Target
+			#
+			$agent target [$self entry]
+			
+			#
+			# Recv Target
+			#
+			$dmux_ install $port $agent
+		}
+	}
+	
+}
+
+Node instproc add-interface { channel pmodel \
+				  lltype mactype qtype qlen iftype anttype} {
+					  
+					  $self instvar arptable_ nifs_
+					  $self instvar netif_ mac_ ifq_ ll_
+					  $self instvar imep_
+					  
+					  #global ns_ opt
+					  #set MacTrace [Simulator set MacTrace_]
+					  
+					  set ns_ [Simulator instance]
+					  
+					  
+					  set imepflag [$ns_ imep-support]
+					  
+					  set t $nifs_
+					  incr nifs_
+					  
+					  set netif_($t)	[new $iftype]		;# interface
+					  set mac_($t)	[new $mactype]		;# mac layer
+					  set ifq_($t)	[new $qtype]		;# interface queue
+					  set ll_($t)	[new $lltype]		;# link layer
+					  set ant_($t)    [new $anttype]
+					  
+					  if {$imepflag == "ON" } {              ;# IMEP layer
+						  set imep_($t) [new Agent/IMEP [$self id]]
+						  set imep $imep_($t)
+						  
+						  set drpT [$ns_ mobility-trace Drop "RTR" $self]
+						  $imep drop-target $drpT
+						  if [info exists namtraceFile_]  {
+							  $drpT namattach $namtraceFile_
+						  }
+						  $ns_ at 0.[$self id] "$imep_($t) start"     ;# start beacon timer
+					  }
+					  
+					  
+					  #
+					  # Local Variables
+					  #
+					  set nullAgent_ [$ns_ set nullAgent_]
+					  set netif $netif_($t)
+					  set mac $mac_($t)
+					  set ifq $ifq_($t)
+					  set ll $ll_($t)
+					  
+					  #
+					  # Initialize ARP table only once.
+					  #
+					  if { $arptable_ == "" } {
+						  set arptable_ [new ARPTable $self $mac]
+						  # FOR backward compatibility sake, hack only
+						  
+						  if {$imepflag != ""} {
+							  set drpT [$ns_ mobility-trace Drop "IFQ" $self]
+						  } else {
+							  set drpT [cmu-trace Drop "IFQ" $self]
+						  }
+						  
+						  $arptable_ drop-target $drpT
+					  }
+					  
+					  #
+					  # Link Layer
+					  #
+					  $ll arptable $arptable_
+					  $ll mac $mac
+					  #	$ll up-target [$self entry]
+					  $ll down-target $ifq
+					  
+					  if {$imepflag == "ON" } {
+						  $imep recvtarget [$self entry]
+						  $imep sendtarget $ll
+						  $ll up-target $imep
+					  } else {
+						  $ll up-target [$self entry]
+					  }
+					  
+					  
+					  
+					  #
+					  # Interface Queue
+					  #
+					  $ifq target $mac
+					  $ifq set qlim_ $qlen
+					  
+					  if {$imepflag != ""} {
+						  set drpT [$ns_ mobility-trace Drop "IFQ" $self]
+					  } else {
+						  set drpT [cmu-trace Drop "IFQ" $self]
+					  }
+					  $ifq drop-target $drpT
+					  
+					  #
+					  # Mac Layer
+					  #
+					  $mac netif $netif
+					  $mac up-target $ll
+					  $mac down-target $netif
+					  #$mac nodes $opt(nn)
+					  set god_ [God instance]
+					  $mac nodes [$god_ num_nodes]
+					  
+					  #
+					  # Network Interface
+					  #
+					  $netif channel $channel
+					  $netif up-target $mac
+					  $netif propagation $pmodel	;# Propagation Model
+					  $netif node $self		;# Bind node <---> interface
+					  $netif antenna $ant_($t)
+					  
+					  #
+					  # Physical Channel`
+					  #
+					  $channel addif $netif
+					  
+					  # ============================================================
+					  
+					  if { [Simulator set MacTrace_] == "ON" } {
+						  #
+						  # Trace RTS/CTS/ACK Packets
+						  #
+						  
+						  if {$imepflag != ""} {
+							  set rcvT [$ns_ mobility-trace Recv "MAC" $self]
+						  } else {
+							  set rcvT [cmu-trace Recv "MAC" $self]
+						  }
+						  $mac log-target $rcvT
+						  if [info exists namtraceFile_]  {
+							  $rcvT namattach $namtraceFile_
+						  }
+						  
+						  
+						  #
+						  # Trace Sent Packets
+						  #
+						  if {$imepflag != ""} {
+							  set sndT [$ns_ mobility-trace Send "MAC" $self]
+						  } else {
+							  set sndT [cmu-trace Send "MAC" $self]
+						  }
+						  $sndT target [$mac down-target]
+						  $mac down-target $sndT
+						  if [info exists namtraceFile_]  {
+							  $sndT namattach $namtraceFile_
+						  }
+						  
+						  #
+						  # Trace Received Packets
+						  #
+						  
+						  if {$imepflag != ""} {
+							  set rcvT [$ns_ mobility-trace Recv "MAC" $self]
+							  
+						  } else {
+							  set rcvT [cmu-trace Recv "MAC" $self]
+						  }
+						  $rcvT target [$mac up-target]
+						  $mac up-target $rcvT
+						  if [info exists namtraceFile_]  {
+							  $rcvT namattach $namtraceFile_
+						  }
+						  
+						  #
+						  # Trace Dropped Packets
+						  #
+						  if {$imepflag != ""} {
+							  set drpT [$ns_ mobility-trace Drop "MAC" $self]
+						  } else {
+							  set drpT [cmu-trace Drop "MAC" $self]`
+						  }
+						  $mac drop-target $drpT
+						  if [info exists namtraceFile_]  {
+							  $drpT namattach $namtraceFile_
+						  }
+					  } else {
+						  $mac log-target [$ns_ set nullAgent_]
+						  $mac drop-target [$ns_ set nullAgent_]
+					  }
+					  
+					  # ============================================================
+					  
+					  $self addif $netif
+				  }
+
+Node instproc agenttrace {tracefd} {
+	
+	set ns_ [Simulator instance]
+	
+	set ragent [$self set ragent_]
+	
+	
+	#
+	# Drop Target (always on regardless of other tracing)
+	#
+	set drpT [$ns_ mobility-trace Drop "RTR" $self]
+	$ragent drop-target $drpT
+	#
+	# Log Target
+	#
+	set T [new Trace/Generic]
+	$T target [$ns_ set nullAgent_]
+	$T attach $tracefd
+	$T set src_ [$self id]
+	#$ragent log-target $T
+	$ragent tracetarget $T
+	
+	#
+	# XXX: let the IMEP agent use the same log target.
+	#
+	set imepflag [$ns_ imep-support]
+	if {$imepflag == "ON"} {
+		[$self set imep_(0)] log-target $T
+	}
+	
+	if [info exists namtraceFile_]  {
+		$drpT namattach $namtraceFile_
+	}
+}
+
+Node instproc nodetrace { tracefd } {
+	
+	set ns_ [Simulator instance]
+	#
+	# This Trace Target is used to log changes in direction
+	# and velocity for the mobile node.
+	#
+	set T [new Trace/Generic]
+	$T target [$ns_ set nullAgent_]
+	$T attach $tracefd
+	$T set src_ [$self id]
+	$self log-target $T    
+
+}
+
+
+Node instproc install-defaulttarget {rcvT} {
+	#set nodetype [[Simulator instance] get-nodetype]
+	$self instvar nodetype_
+	$self install-defaulttarget-New$nodetype_ $rcvT
+	
+}
+
+Node instproc install-defaulttarget-New {rcvT} {
+	[$self set classifier_] defaulttarget $rcvT
+}
+
+Node instproc install-defaulttarget-NewMobile {rcvT} {
+	[$self set classifier_] defaulttarget $rcvT
+}
+
+Node instproc install-defaulttarget-NewBase {rcvT} {
+	
+	$self instvar classifiers_
+	set level [AddrParams set hlevel_]
+	for {set i 1} {$i <= $level} {incr i} {
+		$classifiers_($i) defaulttarget $rcvT
+		#		$classifiers_($i) bcast-receiver $rcvT
+	}
+}
+
+Node instproc install-defaulttarget-NewMIPMH {rcvT} {
+	$self install-defaulttarget-NewBase $rcvT
+}
+
+Node instproc install-defaulttarget-NewMIPBS {rcvT} {
+	$self install-defaulttarget-NewBase $rcvT
+}
+
+
+
+# set receiving power
+Node instproc setPt { val } {
+	$self instvar netif_
+	$netif_(0) setTxPower $val
+}
+
+# set transmission power
+Node instproc setPr { val } {
+	$self instvar netif_
+	$netif_(0) setRxPower $val
+}
+
+Node instproc add-hroute { dst target } {
+	
+	$self instvar classifiers_ rtsize_
+	set al [$self split-addrstr $dst]
+	set l [llength $al]
+	for {set i 1} {$i <= $l} {incr i} {
+		set d [lindex $al [expr $i-1]]
+		if {$i == $l} {
+			$classifiers_($i) install $d $target
+		} else {
+			$classifiers_($i) install $d $classifiers_([expr $i + 1]) 
+		}
+	}
+	#
+	# increase the routing table size counter - keeps track of rtg table size for 
+	# each node
+	set rtsize_ [expr $rtsize_ + 1]
+}
+
+Node instproc test-mcast {} {
+
+	$self instvar classifiers_
+	$self instvar ns_
+	if ![info exist ns_] {
+		set ns_ [Simulator instance]
+	}
+	if [$ns_ multicast?] {
+		$self enable-mcast $ns_
+   }
+	if [$ns_ lbmcast?] {
+		$self enable-lbmcast
+	}
+
+}
diff -urNU5 ns-2.33/tcl/lib/ns-ping.tcl ns-2.33-mobiwan/tcl/lib/ns-ping.tcl
--- ns-2.33/tcl/lib/ns-ping.tcl	1970-01-01 10:00:00.000000000 +1000
+++ ns-2.33-mobiwan/tcl/lib/ns-ping.tcl	2008-05-06 14:40:09.000000000 +1000
@@ -0,0 +1,13 @@
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# PingAgent::recv call TCL proc Agent/Ping recv
+# Amazingly, there was no proc called like this ...
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Agent/Ping instproc recv { src delay } {
+   $self instvar node_
+   set addr [AddrParams get-hieraddr $src]
+   set a [split $addr]
+   set addr [join $a .]
+#   puts "PING [$node_ id] ([$node_ set address_]) - received ECHO from $addr at t=[[Simulator instance] now]  - Round Trip = $delay ms"
+}
+
diff -urNU5 ns-2.33/tcl/lib/ns-route.tcl ns-2.33-mobiwan/tcl/lib/ns-route.tcl
--- ns-2.33/tcl/lib/ns-route.tcl	2008-04-01 13:00:23.000000000 +1100
+++ ns-2.33-mobiwan/tcl/lib/ns-route.tcl	2008-05-06 14:40:09.000000000 +1000
@@ -768,5 +768,84 @@
     return $t
 
 }
 
 
+##################################################
+# MOBIWAN Additions
+##################################################
+
+Simulator instproc compute-route-for-mobilenodes {} {
+	$self instvar MobileNode_
+	Simulator instvar mn_
+	
+	set r [$self get-routelogic]
+	
+	set level [AddrParams set hlevel_]
+	$r hlevel-is $level
+	$self hier-topo $r
+	
+	for {set i 0} {$i < $mn_} {incr i} {
+		set srcID [$MobileNode_($i) node-addr]
+		set bs [$MobileNode_($i) base-station?]
+		set dstID [$bs node-addr]
+		$r hier-insert $srcID $dstID 1  
+		## we donot setup basestn nodes as compute-hier 
+		## takes care of them
+	}
+	$r hier-compute
+
+	$self populate-mobilenode $level
+}
+
+Simulator instproc populate-mobilenode {level} {
+	Simulator instvar mn_
+	$self instvar MobileNode_
+	set i 0
+	
+	while { $i < $mn_ } {
+		set n1 $MobileNode_($i)
+		set addr [$n1 node-addr]
+		set L [$n1 split-addrstr $addr]
+		#
+		# for each hierarchy level, populate classifier 
+		# for that level
+		#
+		for {set k 0} {$k < $level} {incr k} {
+			set csize [AddrParams elements-in-level? $addr $k]
+			#
+			# for each element in that level 
+			# (elements maybe nodes or clusters or domains 
+			#
+			if {$k > 0} {
+				set prefix [$r append-addr $k $L]
+			}
+			for {set m 0} {$m < $csize} {incr m} {
+				if { $m != [lindex $L $k]} {
+					if {$k > 0} {
+						set str $prefix
+						append str . $m
+					} else {
+						set str $m
+					}
+
+					set nh [$r hier-lookup $addr \
+							$str]
+					# add entry in clasifier 
+					# only if hier-lookup 
+					# returns a value. 
+					if {$nh != -1} {
+						set node [$self get-node-by-addr $nh]
+						if { $node > 0 } {
+							$n1 add-hroute $str $node
+						}
+					}
+				}
+			}
+		}
+		incr i
+	}
+}
+
+####################################################
+# MOBIWAN Additions End
+####################################################
diff -urNU5 ns-2.33/tcl/lib/ns-topoman.tcl ns-2.33-mobiwan/tcl/lib/ns-topoman.tcl
--- ns-2.33/tcl/lib/ns-topoman.tcl	1970-01-01 10:00:00.000000000 +1000
+++ ns-2.33-mobiwan/tcl/lib/ns-topoman.tcl	2008-05-06 14:40:09.000000000 +1000
@@ -0,0 +1,1498 @@
+#
+# This software comprises contributed code made by Motorola, as a 
+# Contributor, to Network Simulator NS-2 software provided by the 
+# Regents of the University of California.
+# (Copyright; Regents of the University of California, 1994)
+# The contributed code was made as a result of a partnership between 
+# Motorola and INRIA Rhone-Alpes. 
+#
+# Copyright in the contributed code belongs to Motorola Inc. 2001
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+# ALL ADVERTISING MATERIALS MENTIONING FEATURES OR USE OF THIS SOFTWARE MUST 
+# DISPLAY AN ACKNOWLEDGEMENT TO THE COPYRIGHT OWNERS. 
+# ANY REDISTRIBUTION OF THIS SOFTWARE MUST CONTAIN THE ABOVE COPYRIGHT NOTICES, 
+# CONDITIONS AND DISCLAIMER.
+#
+#
+# ############################################################################
+# This code was developed by Thierry Ernst (1998-2001)
+# MOTOROLA Labs Paris FRANCE - INRIA Rhone-Alpes Grenoble (PLANETE) FRANCE 
+# NS-2.1b6 enhancements for Wide-Area mobility simulations
+#
+# First version coded by Vera Mickael 1999 - Motorola CRM Paris
+# Enhancements by Thierry Ernst 2000-2001 - Motorola / INRIA
+# ############################################################################
+
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Indexes     
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# SITE_NUM:	1...nb_site
+# DOM_NUM:	0...nb_dom-1
+# NODE_NUM:	0...nb_node-1
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Lists and Arrays
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Proc display_ns_XXX:  display after NS object creation
+# tm_all_nodes: array containing ns_object corresponding to node number
+# all_info(node_num)		info of all nodes indexed by node number
+#	1st elem: address
+#	2nd elem: nodetype
+#	3rd elem: other args depending on node type 
+# tn_prefix[DOM_NUM] -> tn_prefix[0...nb_dom-1] (0.0 ; 0.1 ; ... ; 3.3 ...
+# nb_node			total number of nodes in the topology. 
+# all_mobiles			list of all mobile nodes in simulation
+# tn_sites[NODE_NUM]		site prefixes attached to transit node id
+# all_site_prefix[SITE_NUM]	site prefixes corresponding to a site number 
+# all_dom_prefix[DOMAIN_NUM]	domain prefixes for each admin. domain
+# tn_prefix[DOM_NUM]		prefix of transit nodes in domain
+# transit_nodes[DOM_NUM]	transit nodes id in each domain
+# s_borders[SITE_PREFIX]	border nodes in site
+# s_nodes[SITE_PREFIX]		normal nodes in site
+# s_anchors[SITE_PREFIX]	base stations in site
+# New April 01:
+# nsaddr_		array containing nb of subprefixes for each prefix 
+# addrlevel_		after computation, contains the number of NS
+#			domains / cluster / node / last for each level
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# To do list 
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Proc <is_valid_addr> should be used in more places
+# All <get_proc> should check id, addr, prefix, etc.
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Note about addressing:
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# IP hierarchy: domain / site / subnet / node
+# IP addresses look like W.X.Y.Z:
+# Each TN has its own NS domain
+# Each site has its own NS cluster under TN NS domain
+# BR / SR / BS are subnets
+# MAX_DOM: we need more NS domains, because the last level is used
+# for Mobile Nodes attached to the Base Stations.  With 3 levels for
+# NS addresses, size of routing table is growing rapidly and therefore 
+# the time and memory to compute routes.
+# - each Transit Node and each Site has its own NS Domain
+# - BRs, SRs and BSs in a same site are in the same NS domain and 
+#   have their own NS cluster
+# - MNs are in the same NS cluster as the BS serving as their HA
+# MIN_DOM: we need less NS domains, because we have 4 levels for NS 
+# addresses or we don't need one level for Mobile Nodes specifically.
+# - each Transit Node has its own NS Domain
+# - each Site has a NS cluster in the NS Domain of the TN it is attached to
+# - BRs, SRs (and BSs) in the same site have the same NS Cluster.
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+################################################################
+# Class definition
+################################################################
+Class Topoman
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# args: actually one arg only
+# - specifies how NS addressing will look like
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc init { args } {
+   $self instvar nb_node all_info all_mobiles
+
+   # set nb_dom	0	; # index start 0	  	
+   # set nb_site  0	; # index start 1 !!!
+   set nb_node  0	; # index start 0 
+   set all_mobiles ""
+
+   # NS hierarchical addressing
+   $self instvar nsaddr_ nblevel_ addrtype_ 
+
+   set nsaddr_()	0	; # No NS domain for now	
+
+   if { [info exists args] != 0 } {
+	switch [lindex $args 0] {
+	  WIREDONLY { 
+		set addrtype_ MIN_DOM 
+		set nblevel_ 3 
+	  }
+	  ALL { 
+		set addrtype_ MAX_DOM 
+		set nblevel_ 3 
+	  }	
+	  ENHANCED { 
+		set addrtype_ MIN_DOM 
+		set nblevel_ 4 
+	  } 
+
+	  default {
+		puts "Topoman: option [lindex $args 0] not supported"
+		exit  
+	  }
+	}
+   } else {
+     set addrtype_ MAX_DOM 
+     set nblevel_ 3
+   }
+}
+
+################################################################
+# Methods to build the topology
+################################################################
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 10/2000
+# Add a set of administrative domains
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc tm_add_nb_domains {nb_domain} {
+ 
+   for { set i 0 } { $i < $nb_domain } {incr i} { 
+	$self tm_add_domain
+   } 
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 02/01
+# Add a new administrative domain in the topology  
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc tm_add_domain { } {
+   $self instvar all_dom_prefix transit_nodes
+
+   # Because of NS addressing, several prefixes may belong to the 
+   # same administrative domain.
+   # Init list of domains attached to this administrative domain 
+
+   set nb_dom [$self get_nb_admin_domains]
+   set all_dom_prefix($nb_dom) ""
+
+   # Init list of Transit Nodes attached to this administrative domain
+   set transit_nodes($nb_dom) ""
+   # incr nb_dom
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 01/01
+# Add a set of sites to a transit node
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc tm_add_nb_sites_to_tn_id {tn_id nb_sites} {
+ 
+   for { set i 0 } { $i < $nb_sites } {incr i} { 
+	$self tm_add_site_to_tn_id $tn_id 
+   } 
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 01/01 
+# Add a new site to a transit node given its node id 
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc tm_add_site_to_tn_id { tn_id args} {
+   $self instvar tn_sites s_borders s_nodes s_anchors 
+   $self instvar all_site_prefix addrtype_
+
+   set addr [$self get_addr_by_id $tn_id]
+   if { [$self is_tn $addr] != "TRUE" } {
+      puts "tm_add_site_to_tn: $tn_id is not a valid Transit Node"
+      exit 1
+   } 
+   set dom_prefix [$self get_domain_prefix $addr]
+
+   if { $addrtype_ == "MAX_DOM" } {
+	# Each site has its own NS domain 
+	# Prefix is the NS domain itself 
+   	set site_prefix [$self new_prefix ""] 
+   } else {
+	# Each site has its own NS cluster in the NS domain of the TN 
+	# Prefix is the first NS cluster available in this NS domain
+	 set site_prefix [$self new_prefix $dom_prefix] 
+   }
+   lappend tn_sites($tn_id) $site_prefix  
+
+   # Init list of nodes in this site. 
+   set s_borders($site_prefix)		""
+   set s_nodes($site_prefix)		""
+   set s_anchors($site_prefix)		""
+   set all_site_prefix([expr [$self get_nb_sites] + 1]) 	$site_prefix
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 05/01 
+# Add a transit node to an administrative domain 
+# dom_num is the administrative domain to which belongs the transit node.
+# ID is kept to ensure nodes are created in the right order
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc tm_add_tn_to_domain {id dom_num args} {
+   $self instvar transit_nodes tn_sites all_info tn_prefix
+   $self instvar tn_prefix  all_dom_prefix addrtype_
+   
+   # Check if a corresponding administrative domain already exists 
+   if { [$self is_admin_domain $dom_num]  != "TRUE" } {
+      puts "tm_add_tn_to_domain $dom_num out of scope"
+      exit 1
+   }
+
+   if { [$self check_next_node $id] != "TRUE" } {
+      puts "tm_add_tn_to_domain: Try to id a node with a wrong id ($id)" 
+      exit 1
+   }
+
+   set dom_prefix [$self new_prefix ""]
+
+   if { $addrtype_ == "MAX_DOM" } {
+	# Each transit node has its own NS domain 
+	# Prefix is the next available NS domain 
+	# (i.e. dom_num - 1 digit)
+   	set tn_prefix($dom_prefix) $dom_prefix 
+   } else {
+	# Each transit node has its own NS domain
+	# Prefix is the next available NS cluster for this NS domain 
+	# (i.e. dom_num.0 - 2 digits)
+	set tn_prefix($dom_prefix) [$self new_prefix $dom_prefix] 
+   }
+
+   # We now create a new address with this prefix:
+   set nid [$self new_router_addr $tn_prefix($dom_prefix)]
+
+   lappend all_info($nid) "TRANSIT_NODE"
+   lappend transit_nodes($dom_num) $nid 
+   lappend all_dom_prefix($dom_num) $dom_prefix
+
+   # Init list of sites attached to this transit node
+   set tn_sites($nid) ""
+
+   return $all_info($nid)
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 10/2000
+# Add a border node to the IP site
+# ID is kept to ensure nodes are created with the same ID used
+# to create links. 
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc tm_add_border_to_site {id site_num args} {
+   $self instvar s_borders all_info
+
+   if { [$self check_next_node $id] != "TRUE" } {
+      puts "tm_add_border_node: Try to add a node with a wrong id ($id)" 
+   }
+   set site_prefix [$self get_site_prefix_by_num $site_num]
+   
+   set nid [$self new_router_addr $site_prefix]
+   lappend all_info($nid) "BORDER_NODE"
+   lappend s_borders($site_prefix) $nid
+   return $all_info($nid)
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 10/2000
+# Add a normal node to the IP site
+# ID is kept to ensure nodes are created in the right order
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc tm_add_node_to_site {id site_num args} {
+   $self instvar s_nodes all_info
+  
+   if { [$self check_next_node $id] != "TRUE" } {
+      puts "tm_add_node: Try to id a node with a wrong id ($id)" 
+   }
+
+   set site_prefix [$self get_site_prefix_by_num $site_num]
+   
+   set nid [$self new_router_addr $site_prefix]
+   lappend all_info($nid) "SITE_ROUTER"
+   lappend s_nodes($site_prefix) $nid
+   return $all_info($nid) 
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 10/2000
+# Add a base station to the IP site
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc tm_add_bs_to_node { attach_pt args } {
+   $self instvar all_info s_anchors
+
+   set attach_addr [$self get_addr_by_id $attach_pt]
+   set site_prefix [get_site_prefix $attach_addr] 
+   set nid [$self new_router_addr $site_prefix]
+   lappend all_info($nid) "BASE_STATION"
+   lappend all_info($nid) $attach_addr 
+   set all_info($nid) [concat $all_info($nid) $args]
+   lappend s_anchors($site_prefix) $nid
+   return $all_info($nid) 
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Add a set of nodes within a site.  Links are added after effective
+# NS node creation.
+# Return nb nodes in the whole topology before site network is added
+# Needed during effective link creation (site can be attached to any
+# network topology, link are therefore not bound to some node id) 
+# 
+# nn: number of nodes to add in site
+# site_prefix: site to which nodes gonna be added
+# args: unspecified arguments 
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc tm_add_site_network { nn site_prefix args } {
+   set nb [$self get_nb_nodes]
+   set max [expr $nb + $nn]
+
+   for {set i $nb} {$i < $max} {incr i} {
+     	eval $self tm_add_node $i $site_prefix $args
+   }
+   return $nb
+}
+ 
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 10/2000
+# Add a mobile node to the Base Station given its ID  
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc tm_add_mn_to_bs { attach_pt args} {
+   $self instvar all_mobiles all_info
+  
+   set ha_addr [$self get_addr_by_id $attach_pt]
+ 
+   if { [$self is_bs $ha_addr] == "FALSE" } {
+      puts "tm_add_mn : Wrong base station"
+      exit 1
+   }
+
+   # Mobile addr has same prefix as its HA.
+   set subnet_prefix [get_subnet_prefix $ha_addr]
+   set nid [$self new_host_addr $subnet_prefix]
+    
+   lappend all_info($nid) "MOBILE"
+   lappend all_info($nid) $ha_addr
+   set all_info($nid) [concat $all_info($nid) $args] 
+   lappend all_mobiles $nid 
+   return $all_info($nid) 
+}
+  
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Test 10/2000
+# Add a host to a default router 
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc tm_add_host { attach_pt args} {
+   $self instvar all_info
+  
+   set dr_addr [$self get_addr_by_id $attach_pt]
+ 
+   # Host has same prefix as its Default Router.
+   set subnet_prefix [get_subnet_prefix $dr_addr]
+   set nid [$self new_host_addr $subnet_prefix]
+    
+   lappend all_info($nid) "HOST"
+   lappend all_info($nid) $dr_addr
+   set all_info($nid) [concat $all_info($nid) $args] 
+   return $all_info($nid) 
+}
+
+################################################################
+# NS addressing
+################################################################
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Test 04/01 
+# Create a new NS address prefix  
+# prefix = "" / "X" / "X.Y" / "X.Y.Z"
+# 1st level - corresponds to NS domain_num (domain)
+# 2nd level - corresponds to NS cluster_num (site)
+# 3rd level - corresponds to NS nodes_num (subnet)
+# 4rd level - corresponds to NS last_num (last) [optional] 
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc new_prefix { prefix } {
+   $self instvar nsaddr_ nblevel_ 
+
+   set addr_list [split $prefix "."]
+   set l [llength $addr_list]
+   if { $l == 0 } {
+        set p $nsaddr_($prefix)
+   } elseif { $l < $nblevel_ } {
+        set p $prefix.$nsaddr_($prefix)
+   } else {
+        puts "new_prefix $prefix: try to add more levels ($l) than available ($nblevel_)"
+        exit 1
+   }
+   set nsaddr_($p) 0
+   incr nsaddr_($prefix)
+   return $p
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 04/01
+# Test validity of address (return "FALSE" if out of scope)
+# XXX: could also be used to test validity of a site / subnet prefix
+# by replacing host id by "0"
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
+Topoman instproc is_valid_addr { addr } { 
+   set addr_list [split $addr "."]
+   set dom [lindex $addr_list 0]
+   set site [lindex $addr_list 1]
+   set sub [lindex $addr_list 2]
+   set host [lindex $addr_list 3]
+
+   if { [$self get_nb_prefix ""] > $dom } {
+      if { [$self get_nb_prefix $dom] > $site } {
+   	if { [$self get_nb_prefix $dom.$site] > $sub } {
+   	   if { [$self get_nb_prefix $dom.$site.$sub] > $host } {
+		return "TRUE"
+	   }
+	}
+      }
+     }
+   return "FALSE"
+}
+
+################################################################
+# 
+################################################################
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 02/01 
+# Check if node id is the next available node id before creation.
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc check_next_node {node_id} {
+   # $self instvar nb_node
+
+   if { $node_id != [$self get_nb_nodes] } {
+	return FALSE 
+   } else {
+	return TRUE 
+   }
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 05/2002 
+# Create a new router in a subnet and set its address 
+# Return node_id of newly created subnet router
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc new_router_addr { prefix } {
+   $self instvar nb_node all_info
+   $self instvar nblevel_ addrtype_
+
+   if { $nblevel_ == 3 && $addrtype_ == "MIN_DOM" } {
+      # Router while be in provided subnet
+      set subnet_prefix $prefix
+   } else {
+      # New router = first create a new subnet
+      set subnet_prefix [$self new_prefix $prefix]
+   }
+
+   # Router is first node in the subnet
+   set addr [$self new_prefix $subnet_prefix]
+   set all_info($nb_node) $addr
+   incr nb_node
+   return [expr $nb_node - 1]
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 10/2000
+# Create a new node in subnet.
+# Return node_id of newly created node  
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc new_host_addr { subnet_prefix } {
+   $self instvar nb_node all_info
+
+   set addr [$self new_prefix $subnet_prefix]
+   
+   set all_info($nb_node) $addr
+   incr nb_node
+   return [expr $nb_node -1] 
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 10/2000
+# Return next available address in subnet (but do not create it) 
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc free_host_addr { subnet_prefix } {
+   $self instvar nsaddr_
+   return $subnet_prefix.$nsaddr_($subnet_prefix)
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 12/2000
+# Create Nodes, Links and NS addressing
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc tm_create_topo { } {
+   $self instvar all_info all_mobiles
+   $self instvar tn_sites
+   $self instvar s_borders s_nodes s_anchors nblevel_
+   global tm_all_nodes topo_man
+
+   # Node configuration: call node-config for all nodes
+   if { $nblevel_ == 4 } {
+	enhanced_all_nodes_config	
+   } else {
+   	def_all_nodes_config
+   }
+ 
+   # Reserve necessary space for NS addressing
+   $self set_addr_params
+  
+   # Create all nodes sequentially
+   for { set n 0 } { $n < [$self get_nb_nodes] } { incr n} {
+      switch [lindex $all_info($n) 1] {
+        TRANSIT_NODE {
+           set tm_all_nodes($n) \
+		[eval create-transit-router [lreplace $all_info($n) 1 1]]
+        }
+        BORDER_NODE {
+           set tm_all_nodes($n) \
+		[eval create-border-router [lreplace $all_info($n) 1 1]]
+        }
+        SITE_ROUTER {
+           set tm_all_nodes($n) \
+		[eval create-site-router [lreplace $all_info($n) 1 1]]
+        }
+        BASE_STATION {
+           set tm_all_nodes($n) \
+		[eval create-base-station [lreplace $all_info($n) 1 1]]
+        }
+        MOBILE {
+           set tm_all_nodes($n) \
+		[eval create-mobile [lreplace $all_info($n) 1 1]]
+        }
+        HOST {
+           set tm_all_nodes($n) \
+		[eval create-host [lreplace $all_info($n) 1 1]]
+        }
+
+	# Can add more if needed
+        default {
+          puts "tm_create_topo: [lindex $all_info($n) 1] undefined node type"
+        }
+      }
+   }
+   # Create links
+   tm_build_links
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 04/01 
+# Compute recursively how many sublevel there is in each level
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc get_nb_nextlevel { prefix } {
+   $self instvar nblevel_ addrlevel_
+
+   set addr_list [split $prefix "."]
+   set lev [expr [llength $addr_list] + 1]
+   if { $lev >= $nblevel_} {
+	return [$self get_nb_prefix $prefix] 
+   }
+   for { set i 0 } { $i < [$self get_nb_prefix $prefix] } { incr i } {
+      if { [llength $addr_list] == 0 } {
+	lappend addrlevel_($lev) [$self get_nb_nextlevel $i]
+      } else {
+	lappend addrlevel_($lev) [$self get_nb_nextlevel $prefix.$i]
+      }
+   }
+   return [$self get_nb_prefix $prefix]
+} 
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 04/01 
+# Set NS internal addressing corresponding to the defined topology
+# XXX: this proc depends on the selected addressing format. 
+# XXX: Works for a 4-levels NS-2 addressing.
+#      Not yet tested with other address format, but should work 
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc set_addr_params {} {
+   $self instvar addrlevel_
+   $self instvar nblevel_
+
+   set addrlevel_(0) [$self get_nb_nextlevel ""]  
+   set i [expr [array size addrlevel_] - 1]
+   while { $i  > 0 } {
+        set clist $addrlevel_($i)
+        set counter 0
+        set i [expr $i - 1]
+        set plist $addrlevel_($i)
+        set len [llength $plist]
+        for {set j 0} {$j < $len } {incr j} {
+            set counter [ expr $counter + [lindex $plist $j]]
+        }
+        if {$counter != [llength $clist]  } {
+            return 1
+            puts "\tNb items in $clist is not equal to sum of items in list $plist"
+            puts "Can not set NS addressing."
+            exit 1
+        }
+   }
+
+   # XXXX: we hope that NS variable domain_num etc will be replaced
+   # by something more generic.   Moving to any nb of levels would be
+   # straight forward.  It would be easy to define more hierarchies 
+   # of node in Topoman.
+
+   # Make the conversion between our addressing and NS addressing: 
+   AddrParams set domain_num_ $addrlevel_(0)
+   AddrParams set cluster_num_ $addrlevel_(1)
+   AddrParams set nodes_num_ $addrlevel_(2)
+   if { $nblevel_ == 4 } {
+        AddrParams set last_num_ $addrlevel_(3)
+   }
+}
+
+# ##############################################################
+# Methods to query the topology 
+# ##############################################################
+# Notes about EXISTING NS procedures:
+#
+# The following only work for static nodes (unless specifically enhanced):
+# Simulator instproc get-node-by-addr address
+# Simulator instproc get-node-id-by-addr address
+#
+# The following work for ALL nodes:
+# Node instproc id
+# Node instproc node-addr 
+# ##############################################################
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 09/2000
+# Return information about a particular node
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc node_info {node_index} {
+	global TOPOM
+	return [concat $node_index [$TOPOM set all_info($node_index)]]
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 09/2000
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc get_addr_by_id { id } {
+   $self instvar all_info
+
+   if { [info exists all_info($id)] == 0 } {
+      puts "get_addr_by_id: no node with given id $id"
+      exit 1
+   }
+   return [lindex $all_info($id) 0] 
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 09/2000
+# Return node index according to its address
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc get_node_id_by_addr address {
+   $self instvar all_info
+   set n [$self get_nb_nodes]
+   for {set q 0} {$q < $n} {incr q} {
+      if {[string compare [lindex $all_info($q) 0] $address] == 0} {
+                       return $q
+      }
+   }
+  error "get-node-id-by-addr:Cannot find node with given address"
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 09/2000
+# Return mobile node object corresponding to the ist mobile 
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc get_mobile_by_index { index } {
+   $self instvar all_mobiles 
+
+   if { [info exists all_mobiles] != 0 } {
+	global tm_all_nodes
+   	return $tm_all_nodes([lindex $all_mobiles $index])
+   }
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 01/01
+# Return the nb of wired node in the site    
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc get_nb_routers_by_site { site_prefix } {
+
+   return [llength [$self get_routers_by_site $site_prefix]]
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 09/2000
+# Return number of WIRELESS nodes 
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc get_nb_mobiles {} {
+   $self instvar all_mobiles
+   return [llength $all_mobiles]
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 09/2000
+# Return the number of WIRED and WIRELESS nodes 
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc get_nb_nodes {} {
+   $self instvar nb_node
+   return $nb_node 
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 12/2000
+# Return number of WIRED nodes
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc get_nb_wired_nodes {} {
+   return [expr [$self get_nb_nodes] - [$self get_nb_mobiles]]
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Test 02/01 
+# Returns the total number of administrative domains in the topology
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc get_nb_admin_domains {} {
+   #$self instvar nb_dom
+   #return $nb_dom
+   $self instvar all_dom_prefix 
+   return [array size all_dom_prefix]
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Test 02/01 
+# Returns the total number of sites in the topology
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc get_nb_sites {} {
+#  $self instvar nb_site
+#   return $nb_site
+   $self instvar all_site_prefix 
+   return [array size all_site_prefix]
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Test 04/01 
+# Returns number of sub-prefixes in NS level defined by prefix 
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc get_nb_prefix {prefix} {
+   $self instvar nsaddr_
+   return $nsaddr_($prefix)
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 09/2000
+# List of site prefixes linked to the transit node
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc get_tn_sites {transit_node_id} {
+   $self instvar tn_sites
+   return $tn_sites($transit_node_id)
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Test 02/01 
+# Return a list containing prefixes of all sites in the topology 
+# PS: "virtual" sites used by Transit Nodes are not 
+# (and shouldn't be) included.
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc get_all_sites {} {
+   # $self instvar tn_sites transit_nodes
+
+   $self instvar all_site_prefix
+
+   set all_sites ""
+   # set list_ind [array names all_site_prefix]
+   # foreach i [lsort $list_ind] 
+   foreach i [array names all_site_prefix] {
+   	  lappend all_sites $all_site_prefix($i)
+   } 	
+   return $all_sites
+
+   # for { set d 0 } { $d < $nb_dom } {incr d} {
+   #     foreach tn $transit_nodes($d) {
+   #	  set all_sites [concat $all_sites $tn_sites($tn)] 
+   #    }
+   # }
+   #          return $all_sites 
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 12/2000
+# Return list of Border Routers in the site identified by its prefix
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc get_br_by_site {site_prefix} {
+   $self instvar s_borders
+
+   if {[info exists s_borders($site_prefix)]} {
+      return $s_borders($site_prefix)
+   } else {
+      return ""
+   }
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 8/01
+# Return list of all Transit Nodes in the topology
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc get_all_tn {} {
+  $self instvar transit_nodes
+  set tn_list ""
+  set nb_dom [$self get_nb_admin_domains]
+
+  for { set i 0 } { $i < $nb_dom } {incr i} {
+        set tn_list [concat $tn_list $transit_nodes($i)]
+  }
+  return $tn_list
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 12/2000
+# Return list of all Border Routers in the topology 
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc get_all_br {} {
+  set br_list ""
+  set sites [$self get_all_sites] 
+  foreach site $sites {
+	set br_list [concat $br_list [$self get_br_by_site $site]]
+  }
+  return $br_list 
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 12/2000
+# Return id of site router according to its rank in site
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc get_site_router_by_index {site_prefix rank} {
+   $self instvar s_nodes
+  
+   # I need to check if there is "rank" SR in the site 
+   if { [llength $s_nodes($site_prefix)] >= $rank} {
+      return [lindex $s_nodes($site_prefix) [expr $rank - 1]]
+   } else {
+      puts "get_site_router_by_index $site_prefix $rank: no SR $rank in site" 
+      exit 1
+   } 
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 12/2000
+# Return id the last created router in the site, or a border router
+# Do I neeed this ??????
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc get_last_router {site_prefix} {
+   $self instvar s_nodes s_borders
+
+   if { [llength $s_nodes($site_prefix)] != 0 } {
+	return [lindex $s_nodes($site_prefix) end]
+   } else {
+	return [lindex $s_borders($site_prefix) end]
+   }
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Not tested
+# Return list of all site router in site given its prefix
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc get_srs_by_site {site_prefix} {
+   $self instvar s_nodes 
+
+   if { [llength $s_nodes($site_prefix)] != 0 } {
+	return $s_nodes($site_prefix)
+   } else {
+        return ""
+  }
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 01/01 
+# Return list of Router within a site identified by its prefix
+# Routers = Border Routers + Site Routers   
+# We don't add Base Stations
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc get_routers_by_site {site_prefix} {
+   $self instvar s_borders s_nodes
+
+   set list ""
+   if {[info exists s_nodes($site_prefix)]} {
+      set list [concat $list $s_nodes($site_prefix)]
+   }
+   if {[info exists s_borders($site_prefix)]} {
+      set list [concat $list $s_borders($site_prefix)]
+   } 
+   return $list
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 12/2000
+# Return list of Base Stations in the site identified by its prefix  
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc get_bs_by_site {site_prefix} {
+   $self instvar s_anchors 
+
+   if {[info exists s_anchors($site_prefix)]} {
+      return $s_anchors($site_prefix)
+   } else {
+      return ""
+   }
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 12/2000
+# Return list of all BS ids in the entire topology
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc get_all_bs_id {} {
+   set all_bs ""
+   set sites [$self get_all_sites]
+   foreach site $sites {
+        set all_bs [concat $all_bs [$self get_bs_by_site $site]] 
+   }
+   return $all_bs
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 05/2001 
+# Return list of all MN ids in the entire topology
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc get_all_mn_id {} {
+   $self instvar all_mobiles
+   return $all_mobiles 
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 02/01
+# Return domain prefix according to its index
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc get_dom_prefix_by_num { dom_num } {
+   $self instvar all_dom_prefix
+
+   if { [info exists all_dom_prefix($dom_num)] } {
+        return $all_dom_prefix($dom_num)
+   } else {
+        puts "get_dom_prefix_by_num: wrong number $dom_num"
+        exit 1
+   }
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 12/2000
+# Return site prefix according to its index
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc get_site_prefix_by_num { site_num } {
+   $self instvar all_site_prefix
+
+   # Check that site_num is a valid site num
+   if { [info exists all_site_prefix($site_num)] } {
+        return $all_site_prefix($site_num)
+   } else {
+        puts "get_site_prefix_by_num: wrong site number $site_num"
+        exit 1
+   }
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 12/2000
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc toto_get_site_prefix_by_num { site_num } {
+   global TOPOM
+   return [$TOPOM get_site_prefix_by_num $site_num] 
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Return the domain prefix of an address
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc get_domain_prefix { addr } {
+   if { [$self is_valid_addr $addr] == "TRUE" } { 
+      set addr_list [split $addr "."]
+      return [lindex $addr_list 0]
+   }
+   puts "get_domain_prefix: $addr is not a valid address"
+   exit 1
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Test 02/01 
+# Return the domain prefix corresponding to its number 
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc get_domain_prefix_by_num { dom_num } {
+   $self instvar all_dom_prefix
+ 
+   # Check if a corresponding administrative domain already exists 
+   if ! [info exists all_dom_prefix($dom_num) ] {
+      puts "is_domain_prefix: $dom_num out of scope"
+      exit 1
+   }
+   return $all_dom_prefix($dom_num) 
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Test 01/01
+# Test if there exists a domain corresponding to the given prefix
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc is_domain_prefix { dom_prefix } { 
+   set addr_list [split $dom_prefix "."]
+   set dom [lindex $addr_list 0]
+
+   if { [$self get_nb_prefix ""] > $dom } {
+	return "TRUE"
+   }
+   return "FALSE"
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Test 02/01
+# Check if a corresponding administrative domain already exists 
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc is_admin_domain { dom_num } {
+   $self instvar all_dom_prefix
+
+   if ![info exists all_dom_prefix($dom_num)] {
+	return "FALSE"
+   }
+   return "TRUE"
+} 
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 01/01
+# Test if addr corresponds to a mobile node 
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc is_mobile {addr} {
+   $self instvar all_info
+   if { [$self is_valid_addr $addr] == "TRUE" } {
+      set id [$self get_node_id_by_addr $addr]
+      if { [lindex $all_info($id) 1] == "MOBILE" } {
+	 return TRUE 
+      } 
+   }
+   return FALSE 
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 01/01
+# Test if addr corresponds to a transit node 
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc is_tn {addr} {
+   $self instvar all_info
+   if { [$self is_valid_addr $addr] == "TRUE" } {
+      set id [$self get_node_id_by_addr $addr]
+      if { [lindex $all_info($id) 1] == "TRANSIT_NODE" } {
+	 return TRUE 
+      } 
+   }
+   return FALSE 
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 01/01
+# Test if addr corresponds to a base station
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc is_bs {addr} {
+   $self instvar all_info
+   if { [$self is_valid_addr $addr] == "TRUE" } {
+      set id [$self get_node_id_by_addr $addr]
+      if { [lindex $all_info($id) 1] == "BASE_STATION" } {
+	return TRUE
+      } 
+   } 
+   return FALSE 
+}
+
+################################################################
+# Some fun tools to query the topology
+################################################################
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 03/2001
+# Return randomly the address of a Site Router
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc get_random_sr_addr {} {
+   set nb_site [$self get_nb_sites]
+   set rand_site [expr int(rand()*$nb_site) + 1]
+   set site_prefix [$self get_site_prefix_by_num $rand_site]
+   set site_routers [$self get_routers_by_site $site_prefix]
+   set nb_node [llength $site_routers]
+   set rand_id [expr int(rand()*$nb_node)]
+   set cn_addr [$self get_addr_by_id [lindex $site_routers $rand_id]]
+   return $cn_addr
+}
+
+################################################################
+# Methods to display the topology AFTER NS object creation 
+################################################################
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 05/2001
+# Root proc to display topology AFTER NS object creation
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc display_ns_topo {} {
+   set nb_dom [$self get_nb_admin_domains]
+
+   puts ""
+   puts "  >--------------------- NS Topology ---------------------<"
+   puts ""
+   for {set dom 0} {$dom < $nb_dom } {incr dom} {
+        $self display_ns_domain $dom
+   }
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 09/2000
+# Display details of the domain after NS object creation
+# Subroutine of display_ns_topo 
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc display_ns_domain { dom } {
+   $self instvar transit_nodes tn_sites
+   global tm_all_nodes
+
+   puts "  >----------------- Transit Domain $dom --------------------<"
+   foreach tn $transit_nodes($dom) {
+      set object_id $tm_all_nodes($tn)
+      set node_type [$object_id set nodetype_] 
+      set tn_addr [$object_id set address_]
+      set node_id [$object_id set id_]
+      puts "  Transit Node $node_id: $tn_addr ($object_id) \[$node_type\] :"
+      foreach site $tn_sites($tn) {
+         $self display_ns_site $site 
+      }
+   }
+   puts "  >-------------------------------------------------------<"
+   puts ""
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 09/2000
+# Display details of site
+# Subroutine of display_ns_topo 
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc display_ns_site { site } {
+   $self instvar s_borders s_nodes s_anchors
+
+   puts "    Site $site:"
+   puts "\tBorder Routers "
+   foreach node_index $s_borders($site) {
+        $self display_ns_node_info $node_index 
+    }
+    puts "\tSite Routers "
+    foreach node_index $s_nodes($site) {
+        $self display_ns_node_info $node_index 
+    }
+    puts "\tBase Stations "
+    foreach node_index $s_anchors($site) {
+        $self display_ns_node_info $node_index 
+    }
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 09/2000
+# Display mobile nodes after NS object creation
+# Subroutine of display_ns_topo 
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc display_ns_mobiles {} {
+   $self instvar all_mobiles 
+   global tm_all_nodes
+
+   if { [info exists all_mobiles] == 0 } {
+	return
+   }
+   puts ""
+   puts "  >-------------------- Mobile Nodes ---------------------<"
+   puts "  [$self get_nb_mobiles] mobile nodes:"
+   foreach mobile_index $all_mobiles {
+      set object_id $tm_all_nodes($mobile_index)
+      set node_type [$object_id set nodetype_]
+      set node_id [$object_id id]
+      set node_addr [$object_id node-addr] 
+      puts -nonewline "  Mobile node $node_id: $node_addr ($object_id) \[$node_type\] "
+   }
+   puts ""
+   puts "  >-------------------------------------------------------<"
+   puts ""
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 09/2000
+# Display information about a particular node after NS object creation
+# Subroutine of display_ns_topo 
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc display_ns_node_info {node_index} {
+   global tm_all_nodes      
+   set object_id $tm_all_nodes($node_index) 
+   puts "            - [$object_id set id_]: [$object_id set address_] \
+	($object_id) \[[$object_id set nodetype_]\]  "
+}
+
+################################################################
+# Methods to display the topology BEFORE NS object creation 
+################################################################
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 09/2000
+# Root proc to display topology BEFORE NS object creation
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc display_topo {} {
+
+   puts ""
+   puts "  >----------------- Information about topology --------------------<"
+   set nb_dom  [$self get_nb_admin_domains]
+    
+   puts "  Topology has $nb_dom domains: " 
+   for { set d 0 } { $d < $nb_dom } {incr d } {
+	puts ""
+	$self tm_display_transit_nodes $d
+	puts ""
+   }
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 09/2000
+# Display transit nodes  
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc tm_display_transit_nodes {domain} {
+   $self instvar transit_nodes tn_sites
+
+   puts "  Domain $domain has [llength $transit_nodes($domain)] transit nodes: $transit_nodes($domain)"
+
+   foreach tn_id $transit_nodes($domain) {
+      set nb_site [llength $tn_sites($tn_id)]	
+      puts "    Transit node [$self get_addr_by_id $tn_id] has $nb_site sites" 
+      foreach s $tn_sites($tn_id) { 
+	  $self tm_display_site $s
+      }
+   }
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 09/2000
+# Display details of site
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc tm_display_site {site} {
+   $self instvar s_nodes s_borders s_anchors
+
+   puts "    Site $site:" 
+   puts -nonewline "\t[llength $s_borders($site)] borders ($s_borders($site)) "
+   foreach node_index $s_borders($site) {
+	puts -nonewline "- [$self get_addr_by_id $node_index] "
+   }
+   puts ""
+   puts -nonewline "\t[llength $s_nodes($site)] routers ($s_nodes($site)) "
+   foreach node_index $s_nodes($site) {
+	puts -nonewline "- [$self get_addr_by_id $node_index] "
+   }
+   puts ""
+   puts -nonewline "\t[llength $s_anchors($site)] bs ($s_anchors($site)) "
+   foreach node_index $s_anchors($site) {
+	puts -nonewline "- [$self get_addr_by_id $node_index] "
+   }
+   puts ""
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Display a summary of the topology 
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc display_topo_recap { } {
+   puts ""
+   puts "  >------------------ Topology Summary -------------------<"
+   puts "  [$self get_nb_admin_domains] administrative domains"
+   puts "  [$self get_nb_sites] total number of sites"
+   puts ""
+   puts "  [$self get_nb_wired_nodes] total number of wired nodes"
+   puts "  [$self get_nb_mobiles] mobile nodes"
+   puts "  [$self get_nb_nodes] total number of nodes" 
+   puts "  >-------------------------------------------------------<"
+   puts ""
+}
+ 
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 01/2001
+# Display the list of sites and their associated prefix
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc display_all_site_prefix { } {
+   $self instvar all_site_prefix
+
+   puts ""
+   puts "  >------------------ Sites Prefixes ---------------------<"
+   set nb [$self get_nb_sites]
+   puts "  Total number of sites: $nb"
+   for {set i 1} {$i <= $nb } {incr i} {
+	puts "  Site $i: [$self get_site_prefix_by_num $i]" 
+   }
+   puts "  >-------------------------------------------------------<"
+   puts ""
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 12/2000
+# Display all Border Routers in the topology 
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc display_all_br_info {} {
+   $self instvar all_info
+   puts ""
+   puts "  >----------------- Border Routers --------------------<"
+   set sites [lsort [$self get_all_sites]] 
+   foreach site $sites {
+      set br_list [$self get_br_by_site $site]
+      foreach br_id $br_list {
+        puts "  BR $br_id: [lindex $all_info($br_id) 0]\t\t(site prefix $site)"
+      }
+   }
+   puts "  >-------------------------------------------------------<"
+   puts ""
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Nicely display Base Stations
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc display_all_bs_info {} {
+   puts ""
+   puts "  >-------------------- Base Stations --------------------<"
+   foreach node_index [$self get_all_bs_id] {
+        puts "  [$self node_info $node_index]"
+   }
+   puts "  >-------------------------------------------------------<"
+   puts ""
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Nicely display Mobile Nodes
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc display_all_mn_info {} {
+   puts ""
+   puts "  >----------------------- Mobiles -----------------------<"
+   foreach node_index [$self get_all_mn_id] {
+        puts "  [$self node_info $node_index]"
+   }
+   puts "  >-------------------------------------------------------<"
+   puts ""
+}
+
+################################################################
+# Misc Methods 
+################################################################
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 09/2000
+# Generic proc to return the subnet prefix of an address
+# Prefix 1.1.1.2 = 1.1.1
+# Prefix 1.1.2 = 1.1
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc get_subnet_prefix { addr } {
+   set addr_list [split $addr "."]
+
+   set prefix_list [lrange $addr_list 0 [expr [llength $addr_list] -2] ]
+   set prefix_string [join $prefix_list "."]
+   return $prefix_string
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 09/2000
+# Generic proc to return the site prefix of an address
+# Prefix 1.1.1.2 = 1.1
+# Prefix 1.1.2 = 1
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc get_site_prefix { addr } {
+   set addr_list [split $addr "."]
+
+   set prefix_list [lrange $addr_list 0 [expr [llength $addr_list] -3] ]
+   set prefix_string [join $prefix_list "."]
+   return $prefix_string
+}
+
+# ##############################################################
+# Methods to query the topology 
+# ##############################################################
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc tm_node_info {node_index} {
+   global TOPOM
+   return [$TOPOM node_info $node_index]
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc get_mobile_by_index { index } {
+   global TOPOM
+   return [$TOPOM get_mobile_by_index $index]
+}
+
+# ##############################################################
+# Methods to display information about the topology
+# ##############################################################
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 10/2000
+# Root proc to display all the topology before NS object creation
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc display_all_before {} {
+   $self display_topo 
+   $self display_topo_recap
+   $self display_all_br_info
+   $self display_all_bs_info
+   $self display_all_mn_info
+   $self display_all_site_prefix
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 10/2000
+# Root proc to display all the topology after NS object creation
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc display_all_after {} {
+   $self display_ns_topo 
+   $self display_ns_mobiles
+   $self display_topo_recap
+   $self display_all_br_info
+   $self display_all_bs_info
+   $self display_all_mn_info
+   $self display_all_site_prefix
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Demonstration of Topoman
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc tm_demo-topoman { } {
+  global ns TOPOM
+
+  puts ""
+  puts ">------------ Demonstration of TopomanLib ---------------<"
+  # Display info about all nodes
+  $TOPOM display_topo
+  $TOPOM display_topo_recap
+  puts ""
+  puts -nonewline "  Information about node 1:\t"
+  tm_node_info 1
+  puts ""
+  puts -nonewline "  Sites linked to transit node 10: [$TOPOM get_tn_sites 10]"
+  puts ""
+  puts "  Details of site 1:"
+  $TOPOM display_site [$TOPOM get_site_prefix_by_num 1]
+  puts ""
+  puts "  Details of first domain:"
+  $TOPOM display_domain 0
+  puts "  >-------------------------------------------------------<"
+  puts ""
+}
+
+################################################################
+# Do I need the following ones ?  Not sure this is still working
+################################################################
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 09/2000
+# List NS objects corresponding to all nodes 
+# See Simulator insproc all-nodes-list
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Topoman instproc tm_list_nodes {} {
+   global tm_all_nodes
+
+   set list "" 
+   foreach i [array names tm_all_nodes] {
+	lappend list $tm_all_nodes($i)
+   }
+   set list	
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Useless ?
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc get-wired-only-nodes { } {
+   global ns TOPOM
+   lappend nodeaddr
+   set nodelist [$TOPOM tm_get_wired_only_nodes]
+   foreach n $nodelist {
+        lappend nodeaddr [$ns get-node-by-id $n]
+   }
+   return $nodeaddr
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 05/2000
+# Return addr of mobile node according to the ist mobile 
+#Topoman instproc tm_get_addr_by_mobile_index { i } {
+#
+#   $self instvar tm_mobiles_addr
+#   return [lindex $tm_mobiles_addr $i]
+#}
+
+
+
diff -urNU5 ns-2.33/tcl/lib/proc-display.tcl ns-2.33-mobiwan/tcl/lib/proc-display.tcl
--- ns-2.33/tcl/lib/proc-display.tcl	1970-01-01 10:00:00.000000000 +1000
+++ ns-2.33-mobiwan/tcl/lib/proc-display.tcl	2008-05-06 14:40:09.000000000 +1000
@@ -0,0 +1,94 @@
+#
+# This software comprises contributed code made by Motorola, as a 
+# Contributor, to Network Simulator NS-2 software provided by the 
+# Regents of the University of California.
+# (Copyright; Regents of the University of California, 1994)
+# The contributed code was made as a result of a partnership between 
+# Motorola and INRIA Rhone-Alpes. 
+#
+# Copyright in the contributed code belongs to Motorola Inc. 2001
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+# ALL ADVERTISING MATERIALS MENTIONING FEATURES OR USE OF THIS SOFTWARE MUST 
+# DISPLAY AN ACKNOWLEDGEMENT TO THE COPYRIGHT OWNERS. 
+# ANY REDISTRIBUTION OF THIS SOFTWARE MUST CONTAIN THE ABOVE COPYRIGHT NOTICES, 
+# CONDITIONS AND DISCLAIMER.
+#
+#
+# ############################################################################
+# This code was developed by Thierry Ernst (1998-2001)
+# MOTOROLA Labs Paris FRANCE - INRIA Rhone-Alpes Grenoble (PLANETE) FRANCE 
+# NS-2.1b6 enhancements for Wide-Area mobility simulations
+# ############################################################################
+
+################################################################
+# Display simulation parameters 
+################################################################
+proc display-param { } {
+   global opt infof 
+
+   puts $infof ""
+   puts $infof "Simulation parameters:"
+   puts $infof "\tRecord Interval for trace = every $opt(record_interval) sec"
+
+   puts $infof "Files:"
+   puts $infof "\tBS Configuration file = $opt(bs_config_file)"
+   puts $infof "\tCN Configuration file = $opt(cn_config_file)"
+   puts $infof "\tTopology file = $opt(topo_file)"
+   puts $infof "\tScenario file = $opt(scen_file)"
+   puts $infof "\tTrace file = $opt(tracefile)"
+
+   puts $infof "Variables:"
+   puts $infof "\tRandom Seed = $opt(seed)"
+   puts $infof "\tProtocol = $opt(protocol)"
+   puts $infof "\tStop Time = $opt(stop)"
+   
+   puts $infof "Configuration:"
+   puts $infof "\tnb Mobile Nodes = $opt(mn_nn)"
+   puts $infof "\tnb Correspondent Nodes = $opt(cn_nn)"
+   puts $infof "\tnb Base Stations per site = $opt(bs_nn)"
+   puts $infof "\tTopography: $opt(x) x $opt(y)"
+   puts $infof "\tConfiguration MNs: $opt(mn_config)"
+   puts $infof "\tConfiguration BSs: $opt(bs_config)"
+   puts $infof "\tConfiguration RPs: $opt(rp_config)"
+   puts $infof "\tCN config: $opt(cn_config)"
+   puts $infof "\tCN traffic: $opt(cn_traffic)"
+   puts $infof "\tConfiguration Sites: $opt(site_config)"
+   puts $infof "\tConfiguration Scenario: $opt(scen_config)"
+}
+
+################################################################
+# Display some info about topology / addressing / channels
+# proc tm_XXX needs TOPOMAN Library
+################################################################
+#proc display-all-info { } {
+#  tm_display_all_topo
+#  display_all_channels
+#  display_ns_addr_domain
+#}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Display channels to see what's going on
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc display_all_channels {} {
+   global all_channels
+   puts ""
+   puts "  >---------------------- Channels -----------------------<"
+   foreach i [array name all_channels] {
+        puts "\tStub $i has channel $all_channels($i)"
+   }
+   puts "  >---------------------- [array size all_channels] channels \
+		--------------------<"
+   puts ""
+}
+
diff -urNU5 ns-2.33/tcl/lib/proc-mipv6-config.tcl ns-2.33-mobiwan/tcl/lib/proc-mipv6-config.tcl
--- ns-2.33/tcl/lib/proc-mipv6-config.tcl	1970-01-01 10:00:00.000000000 +1000
+++ ns-2.33-mobiwan/tcl/lib/proc-mipv6-config.tcl	2008-05-06 14:40:09.000000000 +1000
@@ -0,0 +1,185 @@
+#
+# This software comprises contributed code made by Motorola, as a 
+# Contributor, to Network Simulator NS-2 software provided by the 
+# Regents of the University of California.
+# (Copyright; Regents of the University of California, 1994)
+# The contributed code was made as a result of a partnership between 
+# Motorola and INRIA Rhone-Alpes. 
+#
+# Copyright in the contributed code belongs to Motorola Inc. 2001
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+# ALL ADVERTISING MATERIALS MENTIONING FEATURES OR USE OF THIS SOFTWARE MUST 
+# DISPLAY AN ACKNOWLEDGEMENT TO THE COPYRIGHT OWNERS. 
+# ANY REDISTRIBUTION OF THIS SOFTWARE MUST CONTAIN THE ABOVE COPYRIGHT NOTICES, 
+# CONDITIONS AND DISCLAIMER.
+#
+#
+# ############################################################################
+# This code was developed by Thierry Ernst (1998-2001)
+# MOTOROLA Labs Paris FRANCE - INRIA Rhone-Alpes Grenoble (PLANETE) FRANCE 
+# NS-2.1b6 enhancements for Wide-Area mobility simulations
+#
+# How to configure nodes for Mobile IPv6 
+# ############################################################################
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Procs to create nodes according to their function in the topology
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc create-router {address args} {
+    global ns 
+    def_transit_config
+    return  [$ns node $address]
+}
+
+proc create-transit-router {address args} {
+    global ns 
+    def_transit_config
+    return  [$ns node $address]
+}
+
+proc create-border-router {address args} {
+    global ns
+    def_border_config
+    return  [$ns node $address]
+}
+
+proc create-site-router {address args} {
+    global ns
+    def_node_config
+    return  [$ns node $address]
+}
+
+proc create-host {address args} {
+    global ns
+    def_host_config
+    return  [$ns node $address]
+}
+
+proc create-base-station {address attach_pt_addr X Y Z args} {
+   global ns 
+   def_bs_config
+ 
+   # Base Stations in distinct sites listen on distinct channels
+   set channel [set_channel_by_addr $address]
+   $ns set chan $channel
+   set local_node [$ns node $address]
+   $local_node random-motion 0 
+   $local_node set X_ $X 
+   $local_node set Y_ $Y 
+   $local_node set Z_ $Z 
+
+   set attach_pt [$ns get-node-by-addr $attach_pt_addr]
+   $ns duplex-link $attach_pt $local_node 5Mb 2ms DropTail
+   return $local_node
+}
+
+proc create-mobile {home_addr ha_addr X Y Z random args} {
+   global ns
+   def_mobile_config
+
+   # Home site 
+   set channel [set_channel_by_addr $home_addr]
+   $ns set chan $channel
+   set local_node [$ns node $home_addr]
+   $local_node set-ha $ha_addr
+   $local_node set X_ $X 
+   $local_node set Y_ $Y 
+   $local_node set Z_ $Z 
+   $local_node random-motion $random
+
+   set start [lindex $args 0]
+
+   if { $random != 0 } {
+	$ns at $start "$local_node start"
+   }
+   return $local_node
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Default calls to node-config
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc def_all_nodes_config { } {
+    global ns
+ 
+    $ns node-config \
+	-addressType hierarchical 
+}
+
+proc enhanced_all_nodes_config { } {
+    global ns
+ 
+    $ns node-config \
+	-addressType "hierarchical 4 8 8 8 8"
+}
+
+proc def_transit_config { } {
+    global ns
+    $ns node-config \
+	-mipv6 ON \
+	-mipagent CN
+}
+
+proc def_border_config { } {
+    global ns
+    $ns node-config \
+	-mipv6 ON \
+	-mipagent CN 
+}
+
+proc def_node_config { } {
+    global ns
+    $ns node-config \
+	-mipv6 ON \
+	-mipagent CN 
+}
+
+proc def_host_config { } {
+    global ns
+    $ns node-config \
+	-mipv6 ON \
+	-mipagent CN 
+}
+
+proc def_bs_config { } {
+   global ns topo
+   $ns node-config \
+	-mipv6 ON \
+	-mipagent BS \
+	-mobileIP ON \
+	-wiredRouting ON \
+	-adhocRouting Network \
+	-llType LL \
+	-macType Mac/802_11 \
+	-ifqType Queue/DropTail/PriQueue \
+	-ifqLen 50 \
+	-antType Antenna/OmniAntenna \
+	-propType Propagation/TwoRayGround \
+	-phyType Phy/WirelessPhy \
+	-channelType Channel/WirelessChannel \
+	-topoInstance $topo \
+	-agentTrace ON \
+	-routerTrace ON
+}
+
+proc def_mobile_config { } {
+   global ns
+
+   $ns node-config \
+	-mipv6 ON \
+	-mipagent MN \
+	-wiredRouting OFF \
+	-adhocRouting Network \
+	-mobileIP ON 
+}
+
diff -urNU5 ns-2.33/tcl/lib/proc-mobi-config.tcl ns-2.33-mobiwan/tcl/lib/proc-mobi-config.tcl
--- ns-2.33/tcl/lib/proc-mobi-config.tcl	1970-01-01 10:00:00.000000000 +1000
+++ ns-2.33-mobiwan/tcl/lib/proc-mobi-config.tcl	2008-05-06 14:40:09.000000000 +1000
@@ -0,0 +1,849 @@
+#
+# This software comprises contributed code made by Motorola, as a 
+# Contributor, to Network Simulator NS-2 software provided by the 
+# Regents of the University of California.
+# (Copyright; Regents of the University of California, 1994)
+# The contributed code was made as a result of a partnership between 
+# Motorola and INRIA Rhone-Alpes. 
+#
+# Copyright in the contributed code belongs to Motorola Inc. 2001
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+# ALL ADVERTISING MATERIALS MENTIONING FEATURES OR USE OF THIS SOFTWARE MUST 
+# DISPLAY AN ACKNOWLEDGEMENT TO THE COPYRIGHT OWNERS. 
+# ANY REDISTRIBUTION OF THIS SOFTWARE MUST CONTAIN THE ABOVE COPYRIGHT NOTICES, 
+# CONDITIONS AND DISCLAIMER.
+#
+#
+# ############################################################################
+# This code was developed by Thierry Ernst (1998-2001)
+# MOTOROLA Labs Paris FRANCE - INRIA Rhone-Alpes Grenoble (PLANETE) FRANCE 
+# NS-2.1b6 enhancements for Wide-Area mobility simulations
+#
+# This file contains the Topoman Library (ns-topoman.tcl) and contains: 
+# - SCEN_PROC: procedures to configure the simulation scenario.
+# - LOAD_PROC: procedures to read simulation scenario from a file or 
+#   or altenatively passed as argument on the shell command line  
+# ############################################################################
+
+# ##############################################################
+# Misc
+# ##############################################################
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Proc to display info about the simulation scenario 
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc display {flag} {
+   global display_
+   set display_ $flag
+}
+
+proc display? { } {
+   global display_
+   if { ![info exists display_] } {
+      return 0
+   }
+  return $display_
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Proc to display instruction read from file or command line 
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc dinput {flag} {
+   global dinput_
+   set dinput_ $flag
+}
+
+proc dinput? { } {
+   global dinput_
+   if { ![info exists dinput_] } {
+      return 0
+   }
+  return $dinput_
+}
+
+# ##############################################################
+# LOAD_PROCS 
+# helpers methods to read the simulation scenario passed as 
+# arguments on the shell command line or from a file
+# ##############################################################
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Generic proc to load a SCEN_PROC
+# Call should either be load-config <scen_proc> <4> <file> 
+# or <option_name>
+# XXX Not ready for use - to replace all the other proc.
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc load-config { args } {
+   global opt
+
+puts "Not ready"
+exit 
+# if length = 3     
+# set scen_proc [lindex $args 0]
+# set nn [lindex $args 1]
+# set file [lindex $args 2]
+# else
+# set option [lindex $args 0]
+   if { $file != "NONE" } { 
+	# Read config file for nn set-mobile records
+	read-function $scen_proc $nn $file
+   } else {
+	# Read instruction from option
+	if { [dinput?] } {
+	   puts "$opt($option)"
+   	}
+	if { $opt($option) != "NONE" } {
+	   eval  $opt($option)
+	}
+   }
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Load Site configuration  
+# If your topology is generated by GT-ITM and you want one
+# stub to look rather different from the other 
+# XXX: does it still work ? 
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc load-config-site { file } {
+   global opt
+
+   if { $opt(site_file) != "NONE" } {
+      source $opt(site_file)
+   }
+
+   if { $file != "NONE" } { 
+	# Read config file for nn set-site records
+	read-function set-site 1 $file
+   } else {
+	# Read instruction from option or command line 
+	if { [dinput?] } {
+	   puts "$opt(site_config)"
+   	}
+	if { $opt(site_config) != "NONE" } {
+     	   eval  $opt(site_config)
+	}
+   }
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Load Base Stations configuration  
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc load-config-bs { nn file } {
+   global opt
+
+   if { $file != "NONE" } { 
+	# Read config file for nn set-mobile records
+	read-function set-bs $nn $file
+   } else {
+	# Read instruction from option or command line 
+	if { [dinput?] } {
+	   puts "$opt(bs_config)"
+   	}
+	if { $opt(bs_config) != "NONE" } {
+	   eval  $opt(bs_config)
+	}
+   }
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Load Mobile Nodes configuration
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc load-config-mn { nn file} {
+ global opt
+
+ if { $nn > 0 } {
+
+   if { $file != "NONE" } {  
+	# Read config file for nn set-mobile records
+	read-function set-mobile $nn $file
+   } else {
+	# Read instruction from option or command line 
+	if { [dinput?] } {
+	   puts "$opt(mn_config)"
+   	}
+	if { $opt(mn_config) != "NONE" } {
+	   eval  $opt(mn_config)
+	}
+   }
+ # } else {
+ #   puts "load-config-mn: variable mn_nn not set (number of mobiles)"
+ #   exit
+ }
+
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Load selection of Correspondend Nodes 
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc load-config-cn { nn file } {
+   global opt
+
+   if { $nn > 0 } {
+
+      if { $file != "NONE" } {  
+	# Read from file
+	read-function select-cn $nn $file	 
+      } else {
+	   # Read instruction from option or command line 
+	   if { [dinput?] } {
+	      puts "$opt(cn_config)"
+   	   }
+	   if { $opt(cn_config) != "NONE" } {
+	      eval  $opt(cn_config)
+	   }
+      }
+   }
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Load Simulation Scenario
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc load-scen { file } {
+
+   global opt
+   if { $file != "NONE" } { 
+        # Read Mobility scenario from file 
+         read-scen $file 
+   } else {
+	# Read instruction from option or command line 
+	if { [dinput?] } {
+	   puts "$opt(scen_config)"
+   	}
+	if { $opt(scen_config) != "NONE" } {
+     	   eval $opt(scen_config)
+	}
+   }
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Generic Proc that reads a file for a specific instruction 
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc read-function { function nn file } {
+  # nn = total number of records to be read from file 
+  set f [open $file r]
+  set i 0
+
+  while {[gets $f line] >= 0 && $i < $nn } {
+	if { [lindex $line 0] == $function} {
+	     if { [dinput?] } {
+                        puts "Read $line"
+             }
+	     eval $line
+             incr i
+        }
+  }
+  if { $i < $nn } {
+        puts "Wrong $function $i definition in file $file"
+        exit 0
+  }
+  close $f
+  return $i
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Read list of mobile node's CN in configuration file
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc read-cns { file } {
+   # file = file containing list of CNs 
+   set f [open $file r]
+   set i 0
+
+   while {[gets $f line] >= 0 } {
+        if { [lindex $line 0] == "add-cn"} {
+	   if { [dinput?] } {
+                puts "Read new CN: $line"
+           }
+           eval $line
+	   incr i
+	   continue
+        } 
+        if { [lindex $line 0] == "select-cn"} {
+	   if { [dinput?] } {
+                puts "Read new CN: $line"
+           }
+           eval $line
+	   incr i
+	   continue
+        } 
+        if { [lindex $line 0] == "select-random-cn"} {
+	   if { [dinput?] } {
+                puts "Read Select Random CN: $line"
+           }
+           eval $line
+	   incr i
+        }
+   }
+   close $f
+
+   # Return nb records read from file  
+   return $i	  
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Read mobility scenario in mobile node's configuration file
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc read-scen { file } {
+   # file = file containing mobility scenario 
+   # lines in file look like:
+   #    set-stub mob_num stub time
+   #    set-stub 0 7 50
+   set f [open $file r]
+
+   while {[gets $f line] >= 0 } {
+
+	switch -exact [lindex $line 0] {
+	   set-stub { 
+		if { [dinput?] } {
+           	#   puts "Read $line" 
+		}
+		eval $line
+	   }
+	   set-mn-to-bs {
+		if { [dinput?] } {
+           	   puts "Read $line" 
+		}
+		eval $line
+	   }
+	}
+   }
+   close $f
+}
+
+# ##############################################################
+# SCEN_PROC
+# procedures to configure the simulation scenario
+# ##############################################################
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# 23/04/01
+# Select Randomly nn distinct Site Routers and make them
+# correspondent nodes (CN) of the mobile node 
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc add-nn-auto-cn { mob_num nn seed time lftm cn_deltat} {
+   global ns TOPOM
+
+   if { $seed != -1 } {
+      expr int(srand($seed))      
+   }
+   set i 0
+   set temp ""
+   while { $i < $nn } { 
+      set cn_addr [$TOPOM get_random_sr_addr ] 
+
+      # Do not select same CN twice
+      while { [lsearch $temp $cn_addr] != -1 } {
+         set cn_addr [$TOPOM get_random_sr_addr] 
+      }
+      lappend temp $cn_addr
+      incr i 
+      add-auto-cn $mob_num $cn_addr $time [expr $time + $lftm]
+      set time [expr int($time) + $cn_deltat]
+   }
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Select Randomly nn distinct Correspondent Nodes
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc select-random-cn { mob_num nn time} {
+   # select-random-cn <MN_index> <Number of CNs> <Time>
+   # select-random-cn 0 10 0.02
+   global ns opt
+
+   set mob_id [[get_mobile_by_index $mob_num] id]
+   set i 0
+   set cn_list ""
+   while { $i < $nn } { 
+	set rand_id [expr int(rand()*[Node set nn_])]
+
+	if { $rand_id == $mob_id } {
+   	   # Avoid CN = MN
+	   continue
+	}
+	if { [lsearch $cn_list $rand_id] != -1 } {     
+	   # Avoid Duplicate CNs 
+	   continue
+	}
+	lappend cn_list $rand_id
+	incr i
+	set id [[Simulator instance] get-node-by-id $rand_id]
+	set addr [$id set address_]
+	add-cn $mob_num $addr $time $opt(stop)
+   }
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Add Correspondent Node to Mobile Node's Binding List for a 
+# specified amount of time (remove it when over) 
+# CN will receive BUs even if there is no traffic 
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc add-cn { mob_num cn_addr time stop} {
+   # file = file containing list of CNs 
+   # lines in file look like:
+   #    add-cn mob_num cn_addr 
+   global ns opt
+   
+   set cn [$ns get-node-by-addr $cn_addr]
+   set mob [get_mobile_by_index $mob_num]
+
+   # Switch LBM on at CNs in case some nodes only are LBM-enabled
+   if { [$cn lbmcast?] && [info exists opt(lbm_cn_only_)] && $opt(lbm_cn_only_) == 1 } {
+      $ns at $time.01 "[$cn set lbmclassifier_] set lbm_flag_ 1"
+      $ns at $stop "[$cn set lbmclassifier_] set lbm_flag_ 0" 
+   }
+
+   if { $opt(protocol) == "MBU"} {
+      global bu_group 
+      $ns at $time.01 "$cn join-group [$cn set regagent_] $bu_group($mob)"
+      $ns at $stop "$cn leave-group [$cn set regagent_] $bu_group($mob)"
+   } else {
+      $ns at $time.01 "$mob add-cn $cn_addr"
+      $ns at $stop "$mob remove-cn $cn_addr"
+   }
+   if { [dinput?] } {
+      global infof
+      puts $infof "set CN [tm_node_info [$cn id]] ($time/$stop) $opt(cn_traffic)"
+      $ns at $opt(stop) "[$cn set regagent_] dump"
+   }
+  if { $opt(cn_traffic) != "NONE" } {
+     eval $opt(cn_traffic) $cn $mob $time $stop
+  } 
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# 23/04/01
+# Setup traffic between a CN and a MN for a specified amount 
+# of time (remove it when over) 
+# If cn_traffic = NONE, CN won't be detected by MN
+# CN only receives BUs if MN receives traffic since less than the
+# last BU's lifetime.   
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc add-auto-cn { mob_num cn_addr time stop } {
+   global ns opt
+   
+   set cn [$ns get-node-by-addr $cn_addr]
+   set mob [get_mobile_by_index $mob_num]
+
+   if { $opt(protocol) == "MBU"} {
+      global bu_group 
+      $ns at $time.01 "$cn join-group [$cn set regagent_] $bu_group($mob)"
+      $ns at $stop "$cn leave-group [$cn set regagent_] $bu_group($mob)"
+   }
+   if { [dinput?] } {
+      global infof
+      puts $infof "set CN AUTO [tm_node_info [$cn id]] ($time/$stop) $opt(cn_traffic)"
+      $ns at $opt(stop) "[$cn set regagent_] dump"
+   }
+  if { $opt(cn_traffic) != "NONE" } {
+     eval $opt(cn_traffic) $cn $mob $time $stop
+  } 
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Select Correspondent Node for a Mobile Node
+# select-cn <selector> <mob_index> <arrival_time> <arg1> [<option> <>]
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc select-cn { selector mob_num time arg1 args } {
+   global ns opt TOPOM
+
+   switch $selector {
+     NN_SR_RAN {
+	# select-cn <NN_SR_RAN> <mob_num> <start_arrival_time> ... 
+	# ... <delta_arrival_time> <nb_CN> <rand_seed>
+	# 1st CN arrives at <start_arrival_time>
+	# A new CN arrives every <delta_arrival_time>	
+	# and stays until end of simulation
+
+	set cn_deltat $arg1
+	set nn [lindex $args 0] 
+	set seed [lindex $args 1] 
+	if { $seed != -1 } {
+	    expr int(srand($seed))	
+	}
+ 	set i 0
+	set temp ""
+        while { $i < $nn } { 
+	   set cn_addr [$TOPOM get_random_sr_addr ] 
+
+	   # Do not select same CN twice
+	   while { [lsearch $temp $cn_addr] != -1 } {
+		set cn_addr [$TOPOM get_random_sr_addr] 
+	   }
+	   lappend temp $cn_addr
+	   incr i 
+   	   add-cn $mob_num $cn_addr $time $opt(stop)
+	   set time [expr int($time) + $cn_deltat]
+	}
+     }
+     IN_OUT_SR {
+	# select-cn <IN_OUT_SR> <mob_num> <start_arrival_time> ... 
+	# ... <delta_arrival_time> <lifetime> <nb_CN> <rand_seed>
+	# 1st CN arrives at <start_arrival_time>
+	# A new CN arrives every <delta_arrival_time> and leave after <lifetime>
+
+	set cn_deltat $arg1
+	set lftm [lindex $args 0] 
+	set nn [lindex $args 1] 
+	set seed [lindex $args 2] 
+	if { $seed != -1 } {
+	    expr int(srand($seed))	
+	}
+ 	set i 0
+	set temp ""
+        while { $i < $nn } { 
+	   set cn_addr [$TOPOM get_random_sr_addr ] 
+
+	   # Do not select same CN twice
+	   while { [lsearch $temp $cn_addr] != -1 } {
+		set cn_addr [$TOPOM get_random_sr_addr] 
+	   }
+	   lappend temp $cn_addr
+	   incr i 
+   	   add-cn $mob_num $cn_addr $time [expr $time + $lftm]
+	   set time [expr int($time) + $cn_deltat]
+	}
+     }
+     SR-AUTO {
+	# select-cn <SR_AUTO> <mob_num> <start_arrival_time> ... 
+	# ... <delta_arrival_time> <lifetime> <nb_CN> <rand_seed>
+	# 1st CN arrives at <start_arrival_time>
+	# A new CN arrives every <delta_arrival_time>	
+	# and leave after <lifetime>	
+
+	set cn_deltat $arg1
+	set lftm [lindex $args 0] 
+	set nn [lindex $args 1] 
+	set seed [lindex $args 2] 
+	add-nn-auto-cn $mob_num $nn $seed $time $lftm $cn_deltat
+     }
+     SITE_LAST {
+	# Last created node in Site
+	puts "select-cn: SITE_LAST not yet implemented"
+	exit 1	
+	set site_prefix [$TOPOM get_site_prefix_by_num $arg1] 
+	set id [$TOPOM get_last_router $site_prefix
+	set cn_addr [$TOPOM get_addr_by_id $id]
+	add-cn $mob_num $cn_addr $time $opt(stop)
+     }
+     SITE_ROUTER {
+puts "select-cn SIRE_ROUTER not tested"
+exit
+	# Attach CN to some site router 
+	# select-cn SR mob_num time site_num node_rank_within_site stop
+	set site_prefix [$TOPOM get_site_prefix_by_num $arg1] 
+	set rank [lindex $args 0]
+	set stop [lindex $args 1]
+        set id [$TOPOM get_site_router_by_index $site_prefix $rank]
+	set cn_addr [$TOPOM get_addr_by_id $id]
+   	add-cn $mob_num $cn_addr $time $stop 
+     }
+     ID {
+	# Attach CN to node id
+	# select_cn IN mob_num time node_id stop 
+ 	set cn_addr [$TOPOM get_addr_by_id $arg1]
+	set stop [lindex $args 0]
+   	add-cn $mob_num $cn_addr $time $stop 
+     }	
+     ADDR {
+	# Attach CN to node with given addr 
+	# select_cn ADDR mob_num time node_addr stop 
+	set stop [lindex $args 0]
+	if {[$TOPOM is_valid_addr $arg1] == "TRUE" } {
+	   	add-cn $mob_num $arg1 $time $stop
+	} else {
+		puts "select-cn: $arg1 not valid address"
+	        exit 1
+	}
+     }	
+     BR {
+puts "select-cn BR not tested"
+exit
+	# Attach CN to site Border Router (select first one) 
+	# select-cn BR mob_num time site_num
+
+	set site_prefix [$TOPOM get_site_prefix_by_num $arg1] 
+	set rank [lindex $args 0]
+        set id [lindex [$TOPOM get_br_by_site $site_prefix] 0]
+	set cn_addr [$TOPOM get_addr_by_id $id]
+	add-cn $mob_num $cn_addr $time $opt(stop)
+     }
+     RANDOM {
+	# XXX: copy proc select-random-cn HERE
+	puts "select-cn: RANDOM not yet implemented"
+        exit 1
+	
+     }
+     default {
+   	puts "select-cn: undefined intruction $selector"
+	exit 1
+      }
+   }
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Global mobility scerario configuration
+# XXX: should specify stop time as an argument
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc set-scen { selector site_list mob_num interval args } {
+   global opt ns TOPOM
+  
+   switch $selector  {
+     AL {	
+	# Alternate between sites
+   	if { [llength $site_list] == 0 } {
+	   set site_list [$TOPOM get_all_sites]
+        }
+	global scen_time
+	set scen_time 0 
+	eval schedule-movement $mob_num $interval $opt(stop) $site_list
+     }
+
+     NN_RAND {
+	# Alternate between sites randomly selected
+	set nn $site_list
+	set nb_site [$TOPOM get_nb_sites]
+	set seed [lindex $args 0] 
+	if { $seed != -1 } {
+	    expr int(srand($seed))	
+	}
+	set i 0
+	set site_list ""
+	while { $i < $nn } { 
+           set rand_site [expr int(rand()*$nb_site) + 1]
+	   if { [lsearch $site_list $rand_site] == -1} {
+	      lappend site_list $rand_site
+	      incr i 
+	   }	
+	}
+	if { [dinput?] } {
+	   puts "Random sites are $site_list"
+	}
+	global scen_time
+	set scen_time 0 
+	eval schedule-movement $mob_num $interval $opt(stop) $site_list
+     }
+	
+     default {
+        puts "set-scen: undefined intruction $attach_pt"
+        exit 1
+     }
+   }
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc schedule-movement {mob_num interval stop args} {
+   global ns scen_time
+   if { $scen_time < $stop } { 
+      # $ns at $scen_time "eval schedule-movement $mob_num $interval $stop $args"
+      foreach site $args {
+         set-stub $mob_num $site $scen_time 
+         set scen_time [expr $scen_time + $interval] 
+      }
+      $ns at [expr $scen_time - $interval]  "eval schedule-movement $mob_num $interval $stop $args"
+   }
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Make the MN enter in a site  
+# set-stub <MN_index> <Site_Num> <Time>
+# To specifies mobility between sites (global mobility) 
+# XXX: make the check:   
+# XXX  If BS in distinct site/stub than current site/stub:
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc set-stub { mob_num site_num time } {
+   global ns opt 
+   if { $time < $opt(stop) } {
+      $ns at $time "enter-site $mob_num $site_num $time"
+   } 
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# set-mn-to-bs <MN_index> <Base_Station_address> <Time>
+# XXX: do not remember it it's still working 
+# XXX: make the check:   
+# XXX  If BS in distinct site/stub than current site/stub:
+# XXX  do this before $ns at $time "$mob enter_stub BS_prefix"
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc set-mn-to-bs { mob_num bs time } {
+   global ns
+   set mob [get_mobile_by_index $mob_num]
+   $ns at $time "$mob enter_bs $bs"
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Configuration for the mobile node
+# set-mobile <selector> <arg1> <X> <Y> <Z> <random 1|0> [<start> <stop>]  
+# o set-mobile SITE <site_num> <X> <Y> <Z> <random 1|0> [<start> <stop>]
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc set-mobile { selector arg1 args }   {
+   global ns TOPOM
+   switch $selector {
+      SITE { 
+   	if { $arg1 == -1 } {
+      	   # Select first site in list of sites
+      	   set site_prefix [lindex [$TOPOM get_all_sites] 0]
+   	} else {
+   	   set site_prefix [$TOPOM get_site_prefix_by_num $arg1]
+	} 
+
+   	# If several BSs in site, take the first one in site 
+   	set bss [$TOPOM get_bs_by_site $site_prefix]
+   	set ha [lindex $bss 0]
+      }
+      SITE_PREFIX {
+	set site_prefix $arg1
+   	# If several BSs in site, take the first one in site 
+   	set bss [$TOPOM get_bs_by_site $site_prefix]
+   	set ha [lindex $bss 0]
+      }
+      BS_ID {
+	set ha $arg1
+      }
+      default {
+	   puts "set-mobile: undefined selector $selector"
+	   exit 1
+	}
+   }
+
+   if { [dinput?] } { 
+	 global infof 
+	 puts $infof "add MN to [tm_node_info $ha]" 
+   }
+   eval $TOPOM tm_add_mn_to_bs $ha $args 
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Configure Site 
+# Attach a site network to a specified site_prefix   
+# set site_config="set-site BR { 1 }"
+# set site_config="set-site BR { $site_list }"
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc set-site { attach_pt_type site_list } {
+   global ns TOPOM site_net
+ 
+   # Definition of global variable site_net HERE (at first call)
+   # Needed at time of effective link creation
+   
+   if { [llength $site_list] == 0 } {
+	set site_list [$TOPOM get_all_sites]
+   }
+
+   switch $attach_pt_type  {
+     BR {	
+	global site_net_size
+	foreach site $site_list {
+   	   set sp [$TOPOM get_site_prefix_by_num $site]
+	   set site_net($sp) [$TOPOM tm_add_site_network $site_net_size $sp]
+ 
+	   # attach to 1st border node (likely the only one)
+	   set brid [lindex [$TOPOM get_br_by_site $sp] 0]
+	   lappend site_net($sp) $brid
+
+	   if { [dinput?] } {
+		 global infof 
+		 puts $infof "add Site to [tm_node_info $brid]" 
+	   }
+	}
+      }
+      default {
+         puts "set-bs: undefined intruction $attach_pt"
+         exit 1
+      }
+   }
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Configuration of a set of Base Stations
+# Specifies where BSs should be attached and what are their coordinates
+# set-bs <selector> <site_index_list> <X> <Y> <Z>
+# o set-bs RAND <site_list> <X> <Y> <Z>
+# o set-bs RAND <> <X> <Y> <Z>
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc set-bs { selector site_num_list args }   {
+   global ns TOPOM
+
+   # By default, init site_num_list to all site num 
+   if { [llength $site_num_list] == 0 } {
+	#set site_list [$TOPOM get_all_sites]
+	set nb [$TOPOM get_nb_sites]
+	set site_num_list ""
+ 	for { set i 1 } { $i <= $nb } {incr i} {
+		lappend site_num_list $i
+	}
+   }
+
+   foreach site $site_num_list {
+      set site_prefix [$TOPOM get_site_prefix_by_num $site]
+  
+      switch $selector  {
+        BR {					
+	# Attach BS to site Border Router 
+	# attach to 1st border node (likely the only one)
+	# XXX: what if there is no BR ?
+	   set attach_pt_id [lindex [$TOPOM get_br_by_site $site_prefix] 0]
+        }
+        RAND {
+	# attach BS to a random wired node in site 
+	# XXX: what if there is no node in site ?
+	   set site_routers [$TOPOM get_routers_by_site $site_prefix]
+	   set nb_node [llength $site_routers] 
+	   set rand_id [expr int(rand()*$nb_node)]
+	   set attach_pt_id [lindex $site_routers $rand_id]
+	}
+	INDEX {
+        # attach BS to specified ith node in site (SR, BR, ...) 
+        # XXX: what if there is no SR ?
+           set attach_pt_id [$TOPOM get_site_router_by_index $site_prefix [lindex $args 0]
+        }
+	default {
+	   puts "set-bs: undefined intruction $attach_pt"
+	   exit 1
+	}
+      }
+      if { [dinput?] } {
+	 global infof 
+	 puts $infof "add BS to [tm_node_info $attach_pt_id]" 
+      }
+
+   # XXX: do not modify arg list in loop !!! 
+   eval $TOPOM tm_add_bs_to_node $attach_pt_id $args
+   }
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Configuration of one Base Station
+# Specifies where a BS should be attached and what are its coordinates
+# set-bs <selector> <arg1> <X> <Y> <Z>
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc set-one-bs { selector arg1 args }   {
+   global ns TOPOM
+   
+   switch $selector  {
+	ADDR {
+	   # attach BS to a particular addr
+	   puts "set-bs: ADDR not yet implemented"
+	   exit 1
+	}
+        ID {
+	# attach BS to specified node id in site (SR, BR, ...) 
+	# XXX: what if there is no corresponding node ?
+	   set attach_pt_id $arg1 
+	}
+	default {
+	   puts "set-one-bs: undefined intruction $attach_pt"
+	   exit 1
+	}
+   }
+   eval $TOPOM tm_add_bs_to_node $attach_pt_id $args
+}
diff -urNU5 ns-2.33/tcl/lib/proc-mobi-global.tcl ns-2.33-mobiwan/tcl/lib/proc-mobi-global.tcl
--- ns-2.33/tcl/lib/proc-mobi-global.tcl	1970-01-01 10:00:00.000000000 +1000
+++ ns-2.33-mobiwan/tcl/lib/proc-mobi-global.tcl	2008-05-06 14:40:09.000000000 +1000
@@ -0,0 +1,223 @@
+#
+# This software comprises contributed code made by Motorola, as a 
+# Contributor, to Network Simulator NS-2 software provided by the 
+# Regents of the University of California.
+# (Copyright; Regents of the University of California, 1994)
+# The contributed code was made as a result of a partnership between 
+# Motorola and INRIA Rhone-Alpes. 
+#
+# Copyright in the contributed code belongs to Motorola Inc. 2001
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+# ALL ADVERTISING MATERIALS MENTIONING FEATURES OR USE OF THIS SOFTWARE MUST 
+# DISPLAY AN ACKNOWLEDGEMENT TO THE COPYRIGHT OWNERS. 
+# ANY REDISTRIBUTION OF THIS SOFTWARE MUST CONTAIN THE ABOVE COPYRIGHT NOTICES, 
+# CONDITIONS AND DISCLAIMER.
+#
+#
+# ############################################################################
+# This code was developed by Thierry Ernst (1998-2001)
+# MOTOROLA Labs Paris FRANCE - INRIA Rhone-Alpes Grenoble (PLANETE) FRANCE 
+# NS-2.1b6 enhancements for Wide-Area mobility simulations
+# ############################################################################
+# ############################################################################
+# Proc for local-mobility
+# ############################################################################
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Set mobile into a new BS coverage 
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Node/MobileNode instproc enter_bs {oldbs_ newbs_} {
+   # This may require to change X,Y coordinates
+   puts "Node/MobileNode instproc enter_bs not implemented"
+   exit 1
+}
+
+# ############################################################################
+# Proc for global-mobility
+# ############################################################################
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Allow mobile node to receive and send DTGs in new site 
+# => Set Network interface of mobile to a new channel 
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Node/MobileNode instproc enter-site {site_prefix} {
+ global ns
+ $self instvar stack_ ragent_ netif_ 
+ if { [$ns set iface_] == "DUAL" } {
+   set newchan [get_channel_by_prefix $site_prefix]
+   set nulchan [set_null_channel]
+
+   if ![info exists stack_] {
+	set stack_ 0
+   }
+   $netif_($stack_) removechan  
+
+   if { $stack_ == 1 } {
+	set stack_ 0
+   } else {
+	set stack_ 1
+   }
+   $newchan changeif $netif_($stack_)
+
+   # XXX: We should have a proc that return top of the interface stack
+   # XXX: because it may not always be ll_
+   $ragent_ target [$self set ll_($stack_)]
+
+ } else {
+   set newchan [get_channel_by_prefix $site_prefix]
+   $self change_channel $newchan
+ }
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Test 05/01
+# XXX apparently, we don't need this
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Node/MobileNode instproc set-site {site_prefix} {
+   global ns 
+   $self instvar stack_ ragent_ netif_ 
+
+   set newchan [get_channel_by_prefix $site_prefix]
+   if ![info exists stack_] {
+	set stack_ 0
+   }
+   if { $stack_ == 1 } {
+	set stack_ 0
+   } else {
+	set stack_ 1
+   }
+   $newchan changeif $netif_($stack_)
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Test 05/01
+# XXX apparently, we don't need this
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Node/MobileNode instproc leave-site {} {
+   set nulchan [set_null_channel]
+   $nulchan changeif $netif_($stack_)
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Remove netif from previous channel and add it to new channel
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Node/MobileNode instproc change_channel {newchan} {
+   $self instvar netif_
+
+   $newchan changeif $netif_(0)
+   # XXX: Set netif's new downtarget
+   # XXX: Seems to be useless (done by channel ?)
+   # XXX: $netif_(0) channel $newchan
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Returns the channel object corresponding to the site_prefix 
+# Assume there is one channel per site
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc get_channel_by_prefix { site_prefix } {
+   global all_channels
+
+    if ![info exists all_channels($site_prefix)] {
+	puts "get_channel_by_prefix $site_prefix: no channel for this site"
+    }
+    return $all_channels($site_prefix)
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Returns the channel object corresponding to the address
+# Assume there is one channel per site
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc get_channel_by_addr {addr} {
+   global all_channels
+
+   set site_prefix [get_site_prefix $addr]
+   if ![info exists all_channels($site_prefix)] {
+      puts "get_channel_by_addr $addr: no channel for this site"
+   }
+   return $all_channels($site_prefix)
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Set a new channel if no one exists for this site
+# Returns the channel object corresponding to the address
+# Assume there is one channel per site
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc set_channel_by_addr {address} {
+   global all_channels
+
+   set site_prefix [get_site_prefix $address]
+
+   # If no channel has been allocated to this site, create one
+   if ![info exists all_channels($site_prefix)] {
+      set all_channels($site_prefix) [new [[Simulator instance] set channelType_]]
+   }
+   return $all_channels($site_prefix)
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 05/2001
+# Set a fake channel used for "idle" interfaces
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc set_null_channel {} {
+   global all_channels
+
+   # If not already created, create it
+   if ![info exists all_channels(null)] {
+      set all_channels(null) [new [[Simulator instance] set channelType_]]
+   }
+  return $all_channels(null)
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# MN enters a new site (i.e. it moves from one channel to another)
+# In order to limit simulation memory and trace files:
+# - BS(s) in new site start to emit beacons
+# - BS(s) in previous site stop to do so
+# - Then we switch to the new site 
+# - XXX: this may cause problems if more than one MN
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc enter-site {mob_num site_num time} {
+   global ns opt TOPOM
+   set mob [get_mobile_by_index $mob_num]
+
+   # Get BSs in current site and stop beacon emisson
+
+   # First, get the BS I was attached to in order
+   # to determine in which site I was.  Then, find
+   # out what are all the BSs in the same site. 
+   set cbs [$mob get-bs]
+   if { [$TOPOM is_valid_addr $cbs] == "TRUE" } {
+        set cp [get_site_prefix $cbs]
+        set cbs_id_list [$TOPOM get_bs_by_site $cp]
+        foreach cbs_id $cbs_id_list { 
+          set cbs [$ns get-node-by-id $cbs_id]      
+          set cbs_regagent [$cbs set regagent_]
+          $cbs_regagent stop-beacon
+        } 
+   } 
+   # else there is probably no registered BS 
+
+   # Get BSs in new site and start beacon emisson
+   if { $time < $opt(stop) } { 
+      set site_prefix [$TOPOM get_site_prefix_by_num $site_num]
+      set bs_id_list [$TOPOM get_bs_by_site $site_prefix]
+
+      foreach bs_id $bs_id_list { 
+         set bs [$ns get-node-by-id $bs_id]      
+         set bs_regagent [$bs set regagent_]
+         $ns at $time.02 "$bs_regagent start-beacon"
+         # $bs_regagent start-beacon
+      } 
+      $ns at $time.01 "$mob enter-site $site_prefix"
+   }
+}
+
diff -urNU5 ns-2.33/tcl/lib/proc-ping.tcl ns-2.33-mobiwan/tcl/lib/proc-ping.tcl
--- ns-2.33/tcl/lib/proc-ping.tcl	1970-01-01 10:00:00.000000000 +1000
+++ ns-2.33-mobiwan/tcl/lib/proc-ping.tcl	2008-05-06 14:40:09.000000000 +1000
@@ -0,0 +1,54 @@
+
+# ############################################################### 
+# Thierry Ernst 1999/2000
+# INRIA Rhone-Alpes Grenoble FRANCE - MOTOROLA Labs Paris FRANCE 
+# 
+# Tools for traffic generation 
+# ############################################################### 
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 23/04/01
+# Set ping traffic between 2 nodes at regular time interval 
+# Same as set-ping-traffic but params are objects instead of ids.
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc set-ping-int { interval src dst start stop } {
+   global ns
+   set sp [new Agent/Ping]
+   set rp [new Agent/Ping]
+   $ns attach-agent $src $sp 
+   $ns attach-agent $dst $rp
+   $ns connect $sp $rp   
+   $ns at $start "send-ping-packet $sp $start $stop $interval"	
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 30/08/01
+# Set ping traffic between 2 nodes at regular time interval
+# Same as set-ping-int but do not start sending immediately.
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc set-ping-int-wait { interval wait src dst start stop } {
+   global ns
+   set sp [new Agent/Ping]
+   set rp [new Agent/Ping]
+   $ns attach-agent $src $sp
+   $ns attach-agent $dst $rp
+   $ns connect $sp $rp
+   set time [expr int($start) + $wait]
+   $ns at $time "send-ping-packet $sp $time $stop $interval"
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# OK 01/01
+# Schedule traffic between 2 nodes at regular time interval 
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc send-ping-packet { sp time stop interval } { 
+   global ns
+
+   if { $time < $stop } {
+	# puts "send ping at $time"
+        $sp send
+	set time [expr $time + $interval] 
+	$ns at $time "send-ping-packet $sp $time $stop $interval"	
+   }
+}
+
diff -urNU5 ns-2.33/tcl/lib/proc-tools.tcl ns-2.33-mobiwan/tcl/lib/proc-tools.tcl
--- ns-2.33/tcl/lib/proc-tools.tcl	1970-01-01 10:00:00.000000000 +1000
+++ ns-2.33-mobiwan/tcl/lib/proc-tools.tcl	2008-05-06 14:40:09.000000000 +1000
@@ -0,0 +1,158 @@
+
+# ############################################################### 
+# Thierry Ernst 1999/2000
+# INRIA Rhone-Alpes Grenoble FRANCE - MOTOROLA Labs Paris FRANCE 
+# 
+# Generic procedures for simulation
+# ############################################################### 
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Display NS addressing
+# OK 10/2000
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc display_ns_addr_domain {} {
+   puts ""
+   puts "  >-------------------- NS Addressing --------------------<"
+   puts "  Domains (domain_num) : [AddrParams set domain_num_]"
+   puts "  Clusters (cluster_num) : [AddrParams set cluster_num_]"
+   puts "  Nodes (nodes_num) :  [AddrParams set nodes_num_]"
+   #if { [AddrParams set hlevel_] == 4 } {
+   #  puts "  Last (last_num) : [AddrParams set last_num_]"
+   #}
+   puts "  >-------------------------------------------------------<"
+   puts ""
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Counter to follow up where we are
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc counter {time} {
+   global ns 
+   # puts "$time ..."
+   $ns at [expr $time + 50] "counter [expr $time + 50]"
+}  
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Usage
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc Usage {} {
+        global opt argv0
+        puts "Usage: $argv0 \[-stop sec\] \[-seed value\] \[-node numNodes\]"
+        puts "\t\[-tr tracefile\] \[-g\]"
+        exit 1
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Display Command Line
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc DisplayCommandLine {} {
+   global opt argc argv
+
+   puts "* Command Line is:"
+   for {set i 0} {$i < $argc} {incr i} {
+	puts -nonewline "[lindex $argv $i] "
+   }
+   puts ""
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Read arguments from the command line
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc Getopt {} {
+   global opt argc argv
+
+   for {set i 0} {$i < $argc} {incr i} {
+                set key [lindex $argv $i]
+                if ![string match {-*} $key] continue
+                set key [string range $key 1 end]
+                set val [lindex $argv [incr i]]
+                set opt($key) $val
+                if [string match {-[A-z]*} $val] {
+                        incr i -1
+                        continue
+                }
+                switch $key {
+                        ll  { set opt($key) LL/$val }
+                        ifq { set opt($key) Queue/$val }
+                        mac { set opt($key) Mac/$val }
+                }
+   }
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Log Movement
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+proc log-mn-movement { } {
+  global logtimer ns
+  Class LogTimer -superclass Timer
+  LogTimer instproc timeout {} {
+        [get_mobile_by_index 0] log-movement 
+        $self sched 1 
+  }
+  set logtimer [new LogTimer]
+  $logtimer sched 1  
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Dump topology
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Simulator instproc dump-topology { file } {
+        $self instvar topology_dumped started_
+        set started_ 1
+
+        # set topology_dumped 1
+
+        # make sure this does not affect anything else later on !
+        # $self namtrace-all $file
+
+        # Color configuration for nam
+        $self dump-namcolors
+
+        # Node configuration for nam
+        $self dump-namnodes
+
+        # Lan and Link configurations for nam
+        $self dump-namlans
+        $self dump-namlinks
+
+        # nam queue configurations
+        $self dump-namqueues
+
+        # Traced agents for nam
+        $self dump-namagents
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Periodic dump to trace file
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Simulator instproc periodic-dump { trace_file record_interval stop} {
+	set ft 0
+        while { $ft < $stop } {
+                $self at $ft "flush $trace_file"
+                set ft [expr $ft + $record_interval]
+        }
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Dump trace and post the time at which this proc will be
+# executed next.
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Simulator instproc dump-trace { file interval stop} {
+	set now [$self now]
+        flush $file
+        set time [expr $now + $interval]
+	if { $time < $stop } {
+		$self at $time "$self dump-trace $file $interval $stop" 
+        }
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Display some information about a node id
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Simulator  instproc display_node_info {index} { 
+   set node [$self set Node_($index)] 
+   set address [$node set address_] 
+   puts "Node $index: $address ($node) \[[$node set nodetype_]\]" 
+}
+
+
diff -urNU5 ns-2.33/tcl/lib/proc-topo.tcl ns-2.33-mobiwan/tcl/lib/proc-topo.tcl
--- ns-2.33/tcl/lib/proc-topo.tcl	1970-01-01 10:00:00.000000000 +1000
+++ ns-2.33-mobiwan/tcl/lib/proc-topo.tcl	2008-05-06 14:40:09.000000000 +1000
@@ -0,0 +1,132 @@
+#
+# This software comprises contributed code made by Motorola, as a 
+# Contributor, to Network Simulator NS-2 software provided by the 
+# Regents of the University of California.
+# (Copyright; Regents of the University of California, 1994)
+# The contributed code was made as a result of a partnership between 
+# Motorola and INRIA Rhone-Alpes. 
+#
+# Copyright in the contributed code belongs to Motorola Inc. 2001
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+# ALL ADVERTISING MATERIALS MENTIONING FEATURES OR USE OF THIS SOFTWARE MUST 
+# DISPLAY AN ACKNOWLEDGEMENT TO THE COPYRIGHT OWNERS. 
+# ANY REDISTRIBUTION OF THIS SOFTWARE MUST CONTAIN THE ABOVE COPYRIGHT NOTICES, 
+# CONDITIONS AND DISCLAIMER.
+#
+#
+# ############################################################################
+# This code was developed by Thierry Ernst (1998-2001)
+# MOTOROLA Labs Paris FRANCE - INRIA Rhone-Alpes Grenoble (PLANETE) FRANCE 
+# NS-2.1b6 enhancements for Wide-Area mobility simulations
+# ############################################################################
+
+################################################################
+# Create the topology using ns-topoman
+# Requires ns-topoman.tcl 
+################################################################
+proc topo-settings { } {
+   global opt TOPOM mobile topo
+
+   if { [dinput?] } {
+	puts "* Build Topology"
+   }
+
+   # Create the TOPOMAN instance
+   set TOPOM [new Topoman $opt(topoman)]
+
+   # Load the main topology
+   source $opt(topo_file) 
+   tm_load_nodes
+
+   # Load specific site topology (optional)
+   # Useful if topo_file was autmatically generated and if we want to 
+   # add more nodes 
+   load-config-site $opt(site_config_file)
+   
+   # Load Base Stations 
+   load-config-bs $opt(bs_nn) $opt(bs_config_file) 
+
+   # Load Mobile Nodes 
+   if { $opt(protocol) != "RT_TABLE"} {
+	load-config-mn $opt(mn_nn) $opt(config_file)
+   }
+
+   if { $opt(RUN) == "TRUE" || $opt(RUN) == "NAM"} {
+	# Create and define topography
+	set topo        [new Topography]
+	#   set prop        [new $opt(prop)]
+	#   $prop topography $topo
+	$topo load_flatgrid $opt(x) $opt(y)
+
+	# god is a necessary object when wireless is used
+	create-god $opt(mn_nn)
+	# Effectively create Nodes, Links and NS addressing
+	$TOPOM tm_create_topo
+
+   	if { [dinput?] } { 
+		$TOPOM display_all_after
+		display_all_channels
+	} else  {
+		display_ns_addr_domain
+	}
+   } else {
+	# Means we don't want to run NS, we just want to display 
+	# information about the topology. 
+	$TOPOM display_all_before
+   }
+}
+
+################################################################
+# Create the wired topology
+# Modified 05/02 (cleanup to work if some options not set)
+################################################################
+proc wired-topo-settings { } {
+   global opt TOPOM mobile topo
+
+   if { [dinput?] } {
+        puts "* Build Topology"
+   }
+
+    # Create the TOPOMAN instance
+   set TOPOM [new Topoman $opt(topoman)]
+
+   # Load the main topology
+   source $opt(topo_file)
+   tm_load_nodes
+
+   # Load specific site topology (optional)
+   # Useful if topo_file was autmatically generated and if we want to
+   # add more nodes
+   if { [info exists opt(site_config_file] } {
+        load-config-site $opt(site_config_file)
+   }
+
+   if { $opt(RUN) == "TRUE" || $opt(RUN) == "NAM" } {
+        # Effectively create Nodes, Links and NS addressing
+        $TOPOM tm_create_topo
+
+        if { [dinput?] } {
+                $TOPOM display_all_after
+        } else  {
+                display_ns_addr_domain
+        }
+   } else {
+        # This means we don't want to run NS, we just want to display
+        # information about the topology.
+        $TOPOM display_all_before
+   }
+}
+
+
+
diff -urNU5 ns-2.33/tcl/mobiwan/simple-mipv6.tcl ns-2.33-mobiwan/tcl/mobiwan/simple-mipv6.tcl
--- ns-2.33/tcl/mobiwan/simple-mipv6.tcl	1970-01-01 10:00:00.000000000 +1000
+++ ns-2.33-mobiwan/tcl/mobiwan/simple-mipv6.tcl	2008-05-06 14:40:09.000000000 +1000
@@ -0,0 +1,154 @@
+# Basic Mobile IPv6 example without using ns-topoman
+# Needs proc defined in file proc-mipv6-config.tcl
+
+Agent/MIPv6/MN set bs_forwarding_     0       ; # 1 if forwarding from previous BS
+################################################################
+proc log-mn-movement_no_topo { } {
+  global logtimer ns
+  Class LogTimer -superclass Timer
+  LogTimer instproc timeout {} {
+ 	global mobile_
+        $mobile_ log-movement 
+        $self sched 1 
+  }
+  set logtimer [new LogTimer]
+  $logtimer sched 1  
+}
+
+################################################################
+# Create Topology
+################################################################
+proc create-my-topo {} {
+  global ns opt topo mobile_ cn_ mnn_nodes_
+
+  # Create and define topography
+  set topo        [new Topography]
+  #   set prop        [new $opt(prop)]
+  #   $prop topography $topo
+  $topo load_flatgrid 800 800 
+
+  # god is a necessary object when wireless is used
+  # set to a value equal to the number of mobile nodes
+  create-god 5 
+
+  # Call node-config
+  $ns node-config \
+        -addressType hierarchical \
+ 	-agentTrace ON \
+ 	-routerTrace ON 
+
+  # Set NS Addressing
+  AddrParams set domain_num_ 2 
+  AddrParams set cluster_num_ {1 5}
+  AddrParams set nodes_num_ {1 1 3 1 1 1}
+
+  # Create Nodes
+  set cn_ [create-router 0.0.0]
+  set router_ [create-router 1.0.0]
+  set bs1_ [create-base-station 1.1.0 1.0.0 200 200 0]
+  set bs2_ [create-base-station 1.2.0 1.0.0 200 600 0]
+  set bs3_ [create-base-station 1.3.0 1.0.0 600 200 0]
+  set bs4_ [create-base-station 1.4.0 1.0.0 600 600 0]
+  set mobile_ [create-mobile 1.1.1 1.1.0 190 190 0 1 0.01]
+
+
+  # Create Links
+  $ns duplex-link $cn_ $router_ 100Mb 1.80ms DropTail
+  $ns duplex-link $router_ $bs1_ 100Mb 1.80ms DropTail
+  $ns duplex-link $router_ $bs2_ 100Mb 1.80ms DropTail
+
+  display_ns_addr_domain
+}
+
+################################################################
+# End of Simulation
+################################################################
+proc finish { } {
+  global tracef ns namf opt mobile_ cn_
+  
+  puts "Simulation finished" 
+  # Dump the Binding Update List of MN and Binding Cache of HA
+  [[$mobile_ set ha_] set regagent_] dump
+  [$cn_ set regagent_] dump
+  [$mobile_ set regagent_] dump
+
+  $ns flush-trace
+  flush $tracef
+  close $tracef
+  close $namf
+  #puts "running nam with $opt(namfile) ... "
+  #exec nam $opt(namfile) &
+  exit 0
+}
+
+
+################################################################
+# Main 
+################################################################
+proc main { } {
+   global opt ns TOPOM namf n tracef mobile_ cn_ 
+   source ../../tcl/mobility/timer.tcl
+
+   set NAMF out.nam
+   set TRACEF out.tr
+   set INFOF out.info
+
+   set opt(mactrace) ON
+   set opt(NAM) 1 
+   set opt(namfile) $NAMF
+   set opt(stop) 100
+   set opt(tracefile) $TRACEF
+   
+   #>--------------- Extract options from command line ---------------<
+   #Getopt	; # Get option from the command line	
+   #DisplayCommandLine
+   
+   #>---------------------- Simulator Settings ----------------------<
+   set ns [new Simulator]
+   #>------------------------ Open trace files ----------------------<
+   exec rm -f $opt(tracefile)
+   set tracef [open $opt(tracefile) w]
+   #... dump the file
+   $ns trace-all $tracef
+    
+   set namf [open $opt(namfile) w]
+   $ns namtrace-all $namf
+
+   #>------------- Protocol and Topology Settings -------------------<
+   create-my-topo
+   log-mn-movement_no_topo
+   
+   set-cbr
+   # set-ping-int 0.1 $cn_ $mobile_ 10 $opt(stop)
+
+
+   #>----------------------- Run Simulation -------------------------<
+   $ns at $opt(stop) "finish"
+   $ns run
+
+   $ns dump-topology $namf
+   close $namf
+   #puts "running nam with $opt(namfile) ... "
+   #exec nam $opt(namfile) &
+}
+
+proc set-cbr { } {
+   global ns cn_ mobile_
+   set udp [new Agent/UDP]
+   $ns attach-agent $cn_ $udp
+   
+   set dst [new Agent/Null]
+   $ns attach-agent $mobile_ $dst
+   $ns connect $udp $dst
+
+   set src [new Application/Traffic/CBR]
+   $src set packetSize_ 1000
+   $src set rate_ 100k
+   $src set interval_ 0.05
+   $src attach-agent $udp
+   $ns at 20.0 "$src start"
+} 
+
+main
+
+
diff -urNU5 ns-2.33/trace/cmu-trace.cc ns-2.33-mobiwan/trace/cmu-trace.cc
--- ns-2.33/trace/cmu-trace.cc	2008-04-01 13:00:24.000000000 +1100
+++ ns-2.33-mobiwan/trace/cmu-trace.cc	2008-05-06 14:40:09.000000000 +1000
@@ -1217,11 +1217,22 @@
                         break;
 		case PT_DSR:
 			format_dsr(p, offset);
 			break;
 		case PT_MESSAGE:
+		case PT_BU:
+		case PT_BU_HA:
+		case PT_BU_CN:
+		case PT_BU_BS:
+		case PT_BACK:
+		case PT_BREQ:
+		case PT_RADS:
+		case PT_SOL:
+		//case PT_PING:
+		case PT_PING_ECHO:
 		case PT_UDP:
+		case PT_ENCAPSULATED:
 			format_msg(p, offset);
 			break;
 		case PT_TCP:
 		case PT_ACK:
 			format_tcp(p, offset);
diff -urNU5 ns-2.33/trace/trace.cc ns-2.33-mobiwan/trace/trace.cc
--- ns-2.33/trace/trace.cc	2008-04-01 13:00:24.000000000 +1100
+++ ns-2.33-mobiwan/trace/trace.cc	2008-05-06 14:40:09.000000000 +1000
@@ -196,11 +196,12 @@
 	packet_t t = th->ptype();
 	int seqno;
 
 	/* UDP's now have seqno's too */
 	if (t == PT_RTP || t == PT_CBR || t == PT_UDP || t == PT_EXP ||
-	    t == PT_PARETO)
+            t == PT_PARETO || t == PT_BU || t == PT_BU_HA || t == PT_BU_CN || 
+	    t == PT_BU_BS || t == PT_BACK || t == PT_BREQ || t == PT_RADS )
 		seqno = rh->seqno();
         else if (t == PT_RAP_DATA || t == PT_RAP_ACK)
                 seqno = raph->seqno();
 	else if (t == PT_TCP || t == PT_ACK || t == PT_HTTP || t == PT_FTP ||
 	    t == PT_TELNET || t == PT_XCP)
