diff -urN ns-2.1b9/Makefile.in ns-allinone-2.1b9/ns-2.1b9/Makefile.in
--- ns-2.1b9/Makefile.in	Mon Mar 18 17:39:26 2002
+++ ns-allinone-2.1b9/ns-2.1b9/Makefile.in	Fri Jul 12 15:06:41 2002
@@ -18,7 +18,6 @@
 #  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 #
 # @(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/Makefile.in,v 1.245 2002/03/15 19:01:01 ddutta Exp $ (LBL)
-
 #
 # Various configurable paths (remember to edit Makefile.in, not Makefile)
 #
@@ -254,8 +253,10 @@
 	pushback/logging-data-struct.o \
 	pushback/rate-estimator.o \
 	pushback/pushback-queue.o pushback/pushback.o \
-	common/parentnode.o trace/basetrace.o \
+    common/parentnode.o trace/basetrace.o \
 	common/simulator.o asim/asim.o \
+    atm/atmpvc.o atm/atmqos.o atm/atmconditioner.o atm/atmscheduler.o \
+    atm/atm.o atm/aal.o atm/sar.o atm/map-ds.o \
 	@V_STLOBJ@
 
 
@@ -412,6 +413,7 @@
 	tcl/mpls/ns-mpls-simulator.tcl \
 	tcl/lib/ns-pushback.tcl \
 	tcl/lib/ns-srcrt.tcl \
+	tcl/lib/ns-atm.tcl \
 	@V_NS_TCL_LIB_STL@
 
 $(GEN_DIR)ns_tcl.cc: $(NS_TCL_LIB)
diff -urN ns-2.1b9/atm/#atmpvc.cc# ns-allinone-2.1b9/ns-2.1b9/atm/#atmpvc.cc#
--- ns-2.1b9/atm/#atmpvc.cc#	Wed Dec 31 19:00:00 1969
+++ ns-allinone-2.1b9/ns-2.1b9/atm/#atmpvc.cc#	Fri Jul 12 15:06:41 2002
@@ -0,0 +1,267 @@
+/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
+/*
+ * Copyright (c) 1999 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the MASH Research
+ *      Group at the University of California Berkeley.
+ * 4. Neither the name of the University nor of the Research Group may be
+ *    used to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * 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.
+ *
+ * @(#) $Header: /opt/simulators/ns/expt/ns-sow/atm/atmnode.h,v 1.0 2000/06/19 17:35:09 sow Exp $
+ *
+ * Contributed by Sowmya Manjanatha, Dept. of Computer Science, UNH, June 2000 
+ */
+
+#include "atmpvc.h"
+
+
+PVC::PVC(int vp, int vc, AtmTrafprm *rx, AtmTrafprm *tx) {
+	vpi = vp;
+	vci = vc;
+	qos = new AtmQos(rx,tx);
+
+}
+
+
+int PVC::set_args(int vp, int vc, AtmTrafprm *rx, AtmTrafprm *tx) {
+	vpi = vp;
+	vci = vc;
+	qos = new AtmQos(rx,tx);
+
+	return (TCL_OK);
+}
+
+
+static class pvc_dbClass : public TclClass {
+public:
+	pvc_dbClass() : TclClass("pvc_db") {}
+	TclObject* create(int, const char*const*) {
+		return (new pvc_db);
+		
+	}	
+} class_pvc_db;
+
+
+int pvc_db::command(int argc, const char*const* argv) {
+  Tcl& tcl = Tcl::instance();
+
+  if (argc == 11) {
+
+	  if (strcmp("add-pvc",argv[1]) == 0) {
+
+		  //incoming pvc
+		  int vpi = atoi(argv[2]);
+
+		  if(vpi < 0) {
+			  tcl.resultf("PVC DATABASE::invalid value %s",argv[2]);	
+			  return TCL_ERROR;
+		  }
+
+		  int vci = atoi(argv[3]);
+
+		  if(vci < 0) {
+			  tcl.resultf("PVC DATABASE::invalid value %s",argv[3]);	
+			  return TCL_ERROR;
+		  }
+
+
+		  AtmTrafprm *rxtp = (AtmTrafprm*)TclObject::lookup(argv[4]);
+
+		  if(rxtp == NULL) {
+			  tcl.resultf("PVC DATABASE::invalid value %s",argv[4]);	
+			  return TCL_ERROR;
+		  }
+
+		  
+		  AtmTrafprm *txtp = (AtmTrafprm*)TclObject::lookup(argv[5]);		  
+		  
+		  if(rxtp == NULL) {
+			  tcl.resultf("PVC DATABASE::invalid value %s",argv[5]);	
+			  return TCL_ERROR;
+		  }
+
+
+		  PVC p = PVC(vpi,vci,rxtp,txtp);
+
+
+		  if (strcmp(argv[6],"map") != 0) {
+			  tcl.resultf("PVC DATABASE::no outgoing interface to map to");	
+			  return TCL_ERROR;
+		  };
+
+		  path pth;
+		  pth.incoming_pvc = p;
+
+		  //outgoing pvc
+
+		  vpi = atoi(argv[7]);
+
+		  if(vpi < 0) {
+			  tcl.resultf("PVC DATABASE::invalid value %s",argv[7]);	
+			  return TCL_ERROR;
+		  }
+
+		  vci = atoi(argv[8]);
+
+		  if(vpi < 0) {
+			  tcl.resultf("PVC DATABASE::invalid value %s",argv[8]);	
+			  return TCL_ERROR;
+		  }
+
+		  rxtp = (AtmTrafprm*)TclObject::lookup(argv[9]);
+
+		  if(rxtp == NULL) {
+			  tcl.resultf("PVC DATABASE::invalid value %s",argv[9]);	
+			  return TCL_ERROR;
+		  }
+
+		  txtp = (AtmTrafprm*)TclObject::lookup(argv[10]);		  
+		  
+		  if(txtp == NULL) {
+			  tcl.resultf("PVC DATABASE::invalid value %s",argv[10]);	
+			  return TCL_ERROR;
+		  }
+
+		  p = PVC(vpi,vci,rxtp,txtp);
+
+		  pth.outgoing_pvc = p;
+
+		  // building the table
+
+		  if (!(conditioner->cac(pth))) {
+	                  tcl.resultf("PVC DATABASE::resource not available\n");
+			  return TCL_ERROR;
+	          }
+
+		  pvc_table.push_back(pth);
+		  return (TCL_OK);
+	  }
+  }
+
+  if (argc == 3) {
+	  if(strcmp("attach-conditioner",argv[1]) == 0) {
+		  conditioner = (AtmConditioner*)TclObject::lookup(argv[2]);
+		  return TCL_OK;
+	  }
+  }
+
+  return (TclObject::command(argc,argv));
+}
+
+
+PVC *pvc_db::get_outgoing_pvc(int vpi, int vci) {
+	
+	for(unsigned int i=0; i < pvc_table.size(); i++) {
+		int vp = pvc_table[i].incoming_pvc.get_vpi();
+		int vc = pvc_table[i].incoming_pvc.get_vci();
+		if((vp == vpi) && (vc == vci)) 
+			return &(pvc_table[i].outgoing_pvc);
+	} 
+	return (PVC*)NULL;
+}
+
+PVC *pvc_db::get_corresponding_outgoing_pvc(int vpi, int vci) {
+	
+	for(unsigned int i=0; i < pvc_table.size(); i++) {
+		int vp = pvc_table[i].outgoing_pvc.get_vpi();
+		int vc = pvc_table[i].outgoing_pvc.get_vci();
+		
+		if((vp == vpi) && (vc == vci))
+			return &(pvc_table[i].outgoing_pvc);
+	}
+	return (PVC*)NULL;
+}
+
+PVC *pvc_db::get_incoming_pvc(int vpi, int vci) {
+	
+	for(unsigned int i=0; i < pvc_table.size(); i++) {
+		int vp = pvc_table[i].incoming_pvc.get_vpi();
+		int vc = pvc_table[i].incoming_pvc.get_vci();
+		if((vp == vpi) && (vc == vci)) 
+			return &(pvc_table[i].incoming_pvc);
+	} 
+	return (PVC*)NULL;
+}
+
+
+
+AtmQos *pvc_db::incoming_qos_lookup(int vpi, int vci) {
+	
+	AtmQos *q;
+
+	for(unsigned int i=0; i < pvc_table.size(); i++) {
+		int vp = pvc_table[i].incoming_pvc.get_vpi();
+		int vc = pvc_table[i].incoming_pvc.get_vci();
+
+		if((vp == vpi) && (vc == vci)) {
+			q = pvc_table[i].incoming_pvc.get_qos();
+			return q;
+		}
+
+	}
+
+	return (AtmQos *)NULL;
+}
+
+AtmQos *pvc_db::outgoing_qos_lookup(int vpi, int vci) {
+	
+
+	for(unsigned int i=0; i < pvc_table.size(); i++) {
+		int vp = pvc_table[i].outgoing_pvc.get_vpi();
+		int vc = pvc_table[i].outgoing_pvc.get_vci();
+
+		if((vp == vpi) && (vc == vci))
+			return pvc_table[i].outgoing_pvc.get_qos();
+
+	}
+
+	return (AtmQos *)NULL;
+}
+
+path *pvc_db::get_corresponding_table_entry(int vpi, int vci) {
+
+	for(unsigned int i=0; i < pvc_table.size(); i++) {
+
+		int vp = pvc_table[i].outgoing_pvc.get_vpi();
+		int vc = pvc_table[i].outgoing_pvc.get_vci();
+
+		if((vpi == vp) && (vci == vc))
+			return (path *)(&(pvc_table[i]));
+	}
+
+	return (path *)NULL;
+}
+
+double pvc_db::get_total_input_rate() {
+
+	double sum = 0.0;
+
+	for (unsigned int i=0; i < pvc_table.size(); i++) 
+		sum += pvc_table[i].input_rate;
+
+	return sum;
+}
diff -urN ns-2.1b9/atm/CHANGES ns-allinone-2.1b9/ns-2.1b9/atm/CHANGES
--- ns-2.1b9/atm/CHANGES	Wed Dec 31 19:00:00 1969
+++ ns-allinone-2.1b9/ns-2.1b9/atm/CHANGES	Fri Jul 12 15:06:41 2002
@@ -0,0 +1,18 @@
+From the main ns-2.1b7 branch, these files were modified:
+
+1) classifier.cc
+2) trace.cc
+3) ttl.cc
+4) classifier.h
+5) packet.h
+6) Makefile
+7) tcl/lib/ns-default.tcl
+8) tcl/lib/ns-lib.tcl
+9) tcl/lib/ns-packet.tcl
+
+tcl/lib now also contains a new file "ns-atm.tcl".
+
+
+All other required ATM files are in the "atm" directory.
+
+
diff -urN ns-2.1b9/atm/README ns-allinone-2.1b9/ns-2.1b9/atm/README
--- ns-2.1b9/atm/README	Wed Dec 31 19:00:00 1969
+++ ns-allinone-2.1b9/ns-2.1b9/atm/README	Fri Jul 12 15:06:41 2002
@@ -0,0 +1,25 @@
+Steps for compiling the ATM simulator
+-------------------------------------
+
+I have assumed here that tcl8.3.2/tk8.3.2, otcl version 6, tclcl version 10
+are all previously installed on your current directory.  
+
+1) Untar and unzip the ns-2.1b7 version on to this directory.  
+   tar xvzf ns-2.1b7.tar.gz
+
+2) Then cp your atm patch to the directory you have ns-2.1b7 directory.
+   Untar and unzip the patch
+    tar xvzf ns-2.1b7-atm-patch.tgz
+
+3)cd into ns-2.1b7
+
+4)A simple 
+
+     ./configure
+     make
+     make install
+
+   should get you going.  If not, check all your paths for the TCL, OTCL
+   and TCLCL.
+
+   Read the installation instructions from the NS home page for more details.
diff -urN ns-2.1b9/atm/README.aux ns-allinone-2.1b9/ns-2.1b9/atm/README.aux
--- ns-2.1b9/atm/README.aux	Wed Dec 31 19:00:00 1969
+++ ns-allinone-2.1b9/ns-2.1b9/atm/README.aux	Fri Jul 12 15:06:41 2002
@@ -0,0 +1,5 @@
+\relax 
+\@writefile{toc}{\contentsline {section}{\numberline {1}08/18/2000}{1}}
+\@writefile{toc}{\contentsline {subsection}{\numberline {1.1}Changes made to the existing NS Source:}{1}}
+\@writefile{toc}{\contentsline {section}{\numberline {2}08/29/2000}{3}}
+\@writefile{toc}{\contentsline {subsection}{\numberline {2.1}Changes made to existing NS Source}{3}}
Binary files ns-2.1b9/atm/README.dvi and ns-allinone-2.1b9/ns-2.1b9/atm/README.dvi differ
diff -urN ns-2.1b9/atm/README.log ns-allinone-2.1b9/ns-2.1b9/atm/README.log
--- ns-2.1b9/atm/README.log	Wed Dec 31 19:00:00 1969
+++ ns-allinone-2.1b9/ns-2.1b9/atm/README.log	Fri Jul 12 15:06:41 2002
@@ -0,0 +1,110 @@
+This is TeX, Version 3.14159 (Web2C 7.3.1) (format=latex 2000.3.7)  29 AUG 2000 11:22
+**README.tex
+(README.tex
+LaTeX2e <1998/12/01> patch level 1
+Babel <v3.6x> and hyphenation patterns for american, french, german, ngerman, i
+talian, nohyphenation, loaded.
+(/usr/share/texmf/tex/latex/base/article.cls
+Document Class: article 1999/01/07 v1.4a Standard LaTeX document class
+(/usr/share/texmf/tex/latex/base/size12.clo
+File: size12.clo 1999/01/07 v1.4a Standard LaTeX file (size option)
+)
+\c@part=\count79
+\c@section=\count80
+\c@subsection=\count81
+\c@subsubsection=\count82
+\c@paragraph=\count83
+\c@subparagraph=\count84
+\c@figure=\count85
+\c@table=\count86
+\abovecaptionskip=\skip41
+\belowcaptionskip=\skip42
+\bibindent=\dimen102
+)
+(/usr/share/texmf/tex/generic/misc/psfig.sty
+\@unused=\write3
+\ps@stream=\read1
+\p@intvaluex=\dimen103
+\p@intvaluey=\dimen104
+
+psfig/tex 1.10-dvips
+) (/usr/share/texmf/tex/latex/graphics/graphics.sty
+Package: graphics 1999/02/16 v1.0l Standard LaTeX Graphics (DPC,SPQR)
+
+(/usr/share/texmf/tex/latex/graphics/trig.sty
+Package: trig 1999/03/16 v1.09 sin cos tan (DPC)
+)
+(/usr/share/texmf/tex/latex/config/graphics.cfg)
+Package graphics Info: Driver file: dvips.def on input line 80.
+
+(/usr/share/texmf/tex/latex/graphics/dvips.def
+File: dvips.def 1999/02/16 v3.0i Driver-dependant file (DPC,SPQR)
+)) (README.aux)
+\openout1 = `README.aux'.
+
+LaTeX Font Info:    Checking defaults for OML/cmm/m/it on input line 16.
+LaTeX Font Info:    ... okay on input line 16.
+LaTeX Font Info:    Checking defaults for T1/cmr/m/n on input line 16.
+LaTeX Font Info:    ... okay on input line 16.
+LaTeX Font Info:    Checking defaults for OT1/cmr/m/n on input line 16.
+LaTeX Font Info:    ... okay on input line 16.
+LaTeX Font Info:    Checking defaults for OMS/cmsy/m/n on input line 16.
+LaTeX Font Info:    ... okay on input line 16.
+LaTeX Font Info:    Checking defaults for OMX/cmex/m/n on input line 16.
+LaTeX Font Info:    ... okay on input line 16.
+LaTeX Font Info:    Checking defaults for U/cmr/m/n on input line 16.
+LaTeX Font Info:    ... okay on input line 16.
+
+Underfull \hbox (badness 10000) in paragraph at lines 27--32
+
+ []
+
+LaTeX Font Info:    Try loading font information for OMS+cmr on input line 41.
+(/usr/share/texmf/tex/latex/base/omscmr.fd
+File: omscmr.fd 1998/03/27 v2.5g Standard LaTeX font definitions
+)
+LaTeX Font Info:    Font shape `OMS/cmr/m/n' in size <12> not available
+(Font)              Font shape `OMS/cmsy/m/n' tried instead on input line 41.
+
+Underfull \hbox (badness 10000) in paragraph at lines 52--56
+
+ []
+
+
+Underfull \hbox (badness 10000) in paragraph at lines 52--56
+
+ []
+
+
+Underfull \hbox (badness 10000) in paragraph at lines 63--74
+
+ []
+
+[1
+
+]
+Underfull \hbox (badness 10000) in paragraph at lines 75--76
+
+ []
+
+
+Underfull \hbox (badness 10000) in paragraph at lines 92--103
+
+ []
+
+
+Underfull \hbox (badness 10000) in paragraph at lines 104--109
+
+ []
+
+[2] [3] [4] (README.aux) ) 
+Here is how much of TeX's memory you used:
+ 658 strings out of 10898
+ 6896 string characters out of 96882
+ 56580 words of memory out of 263001
+ 3643 multiletter control sequences out of 10000+0
+ 6229 words of font info for 23 fonts, out of 400000 for 1000
+ 14 hyphenation exceptions out of 1000
+ 22i,4n,19p,192b,287s stack positions out of 300i,100n,500p,50000b,4000s
+
+Output written on README.dvi (4 pages, 7904 bytes).
diff -urN ns-2.1b9/atm/README.ps ns-allinone-2.1b9/ns-2.1b9/atm/README.ps
--- ns-2.1b9/atm/README.ps	Wed Dec 31 19:00:00 1969
+++ ns-allinone-2.1b9/ns-2.1b9/atm/README.ps	Fri Jul 12 15:06:41 2002
@@ -0,0 +1,963 @@
+%!PS-Adobe-2.0
+%%Creator: dvips(k) 5.86 Copyright 1999 Radical Eye Software
+%%Title: README.dvi
+%%Pages: 4
+%%PageOrder: Ascend
+%%BoundingBox: 0 0 596 842
+%%EndComments
+%DVIPSWebPage: (www.radicaleye.com)
+%DVIPSCommandLine: dvips README.dvi -o README.ps
+%DVIPSParameters: dpi=600, compressed
+%DVIPSSource:  TeX output 2000.08.29:1122
+%%BeginProcSet: texc.pro
+%!
+/TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S
+N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72
+mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0
+0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{
+landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize
+mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[
+matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round
+exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{
+statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0]
+N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin
+/FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array
+/BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2
+array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N
+df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A
+definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get
+}B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub}
+B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr
+1 add N}if}B/id 0 N/rw 0 N/rc 0 N/gp 0 N/cp 0 N/G 0 N/CharBuilder{save 3
+1 roll S A/base get 2 index get S/BitMaps get S get/Cd X pop/ctr 0 N Cdx
+0 Cx Cy Ch sub Cx Cw add Cy setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx
+sub Cy .1 sub]/id Ci N/rw Cw 7 add 8 idiv string N/rc 0 N/gp 0 N/cp 0 N{
+rc 0 ne{rc 1 sub/rc X rw}{G}ifelse}imagemask restore}B/G{{id gp get/gp
+gp 1 add N A 18 mod S 18 idiv pl S get exec}loop}B/adv{cp add/cp X}B
+/chg{rw cp id gp 4 index getinterval putinterval A gp add/gp X adv}B/nd{
+/cp 0 N rw exit}B/lsh{rw cp 2 copy get A 0 eq{pop 1}{A 255 eq{pop 254}{
+A A add 255 and S 1 and or}ifelse}ifelse put 1 adv}B/rsh{rw cp 2 copy
+get A 0 eq{pop 128}{A 255 eq{pop 127}{A 2 idiv S 128 and or}ifelse}
+ifelse put 1 adv}B/clr{rw cp 2 index string putinterval adv}B/set{rw cp
+fillstr 0 4 index getinterval putinterval adv}B/fillstr 18 string 0 1 17
+{2 copy 255 put pop}for N/pl[{adv 1 chg}{adv 1 chg nd}{1 add chg}{1 add
+chg nd}{adv lsh}{adv lsh nd}{adv rsh}{adv rsh nd}{1 add adv}{/rc X nd}{
+1 add set}{1 add clr}{adv 2 chg}{adv 2 chg nd}{pop nd}]A{bind pop}
+forall N/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn
+/BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put
+}if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{
+bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A
+mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{
+SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{
+userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X
+1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4
+index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N
+/p{show}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 N/Ry 0 N/V{}B/RV/v{
+/Ry X/Rx X V}B statusdict begin/product where{pop false[(Display)(NeXT)
+(LaserWriter 16/600)]{A length product length le{A length product exch 0
+exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}ifelse
+end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{BDot}imagemask
+grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat{BDot}
+imagemask grestore}}ifelse B/QV{gsave newpath transform round exch round
+exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 rlineto
+fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B/M{S p
+delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M}B/g{0 M}
+B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p -3 w}B/n{
+p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{0 S
+rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end
+
+%%EndProcSet
+TeXDict begin 39158280 55380996 1000 600 600 (README.dvi)
+@start
+%DVIPSBitmapFont: Fa cmtt12 12 38
+/Fa 38 126 df<00085B003EEB07C0007FEB0FE0A24814F0A26C14E0B3A2007E1307003E
+14C0A20008EB01001C1E75BD33>34 D<EA07C0EA0FF0EA1FF8123F13FCA213FEA2121F12
+0F1207EA007E13FEA213FC1201EA03F81207EA0FF0EA7FE012FF13C013005A12780F196E
+8A33>44 D<121FEA3F80EA7FC0EAFFE0A5EA7FC0EA3F80EA1F000B0B6C8A33>46
+D<167816F8ED01FCA21503A2ED07F8A2ED0FF0A2ED1FE0A216C0153FA2ED7F80A2EDFF00
+A24A5AA25D1403A24A5AA24A5AA24A5AA25D143FA24A5AA24AC7FCA2495AA25C1303A249
+5AA2495AA25C131FA2495AA2495AA249C8FCA25B1201A2485AA2485AA2485AA25B121FA2
+485AA2485AA248C9FCA25AA2127CA2264D7AC433>I<EA07C0EA0FE0EA1FF0EA3FF8A5EA
+1FF0EA0FE0EA07C0C7FCB3A3EA07C0EA0FE0EA1FF0EA3FF8A213FCA3121F120F12071200
+A2120113F81203EA07F0120FEA1FE0127FEAFFC01380130012FC12700E396EAA33>59
+D<007FB71280A2B812C0A36C16806C1600CBFCA9003FB7FC481680B812C0A36C1680A22A
+177CA933>61 D<EC1F804A7E4A7EA34A7EA314F901017FA501037FA214F0A201077FA4EC
+E07E010F137FA449486C7EA549486C7EA4017F80EC000FA291B5FCA290B67EA43A01FE00
+07F8491303A4000381491301A3000781491300D87FFF90380FFFE0B56C4813F06E5AA24A
+7E6C496C13E02C3E7DBD33>65 D<91391FE00780DAFFFC13C00103EBFF0F010F148F4914
+FF5B90387FF81F9038FFC00748497E4848487E497F485A167F485A49143F121F5B003F15
+1F5BA2127F90C8EA0F8093C7FCA25A5AAD7E7EA36DEC0F80003FED1FC0A27F121F7F000F
+153F6D15806C7E167F6C6CECFF007F3A01FF8003FE6C6D485A90397FF81FF86DB55A6D5C
+6D5C010391C7FC010013FCEC1FE02A3F7CBD33>67 D<91387F803C903901FFF03E0107EB
+FC7E011F13FE49EBFFFE5B9038FFE07F48EB803FEC000FEA03FC00071407491303485A49
+1301121F5B123F491300A2127F90C8FC167C93C7FCA25A5AA992387FFFC092B512E0A37E
+6C6E13C0923800FE00A36D1301123FA27F121F6D1303120F7F6C6C1307A26C6C130F6C6C
+131F9038FF803F6CEBE0FF6DB5FC7F6D13FE010713F80101EBF07C9026007F80C7FC2B3F
+7CBD33>71 D<3B7FFFC00FFFF8B56C4813FCA46C496C13F8D803F8C7EA7F00B3A290B7FC
+A601F8C77EB3A53B7FFFC00FFFF8B56C4813FCA46C496C13F82E3D7EBC33>I<D83FF8EC
+1FFC486CEC3FFE486CEC7FFFA2007F16FE6C6CECFFFC000716E001EF14F7EC8001A39039
+E7C003E7A3ECE007A201E314C7A2ECF00FA201E11487ECF81FA201E01407A2ECFC3FA2EC
+7C3E157E147EEC3E7CA3EC1E78EC1FF8A2EC0FF0A3EC07E0EC03C091C7FCAED83FFCEC3F
+FC486CEC7FFEB591B5FCA26C48EC7FFE6C48EC3FFC303D7FBC33>77
+D<D87FFC90381FFFE0486C4913F07FA36C6D6C13E00003913800FC0013F780A213F380A3
+EBF1F0A38013F0A280A2147C147EA2143E143FA2801580A3140F15C0A2140715E0A21403
+15F0A21401A215F81400A3157CA3153C153EA2151E151F387FFF80B5EAC00FA315076C49
+6C5A2C3D7DBC33>I<003FB512FC48ECFF80B712E016F86C816C813A01FC000FFF030313
+801500EE7FC0163FEE1FE0160FA217F01607A6160F17E0A2161FEE3FC0167FEEFF801503
+030F130090B65A5E5E16E0168003FCC7FC01FCC9FCB3383FFFE0487FB57EA26C5B6C5B2C
+3D7EBC33>80 D<007FB57EB612F815FE81826C812603F8007FED3FF0ED0FF815076F7E15
+01A26F7EA74B5AA215034B5A150FED3FF0EDFFE090B65A5E93C7FC5D8182D9F8007F153F
+6F7E150F821507AA173E177FA416F8030313FF267FFFC014FEB538E001FF17FC81EE7FF8
+6C49EB3FF0C9EA0FC0303E7EBC33>82 D<003FB712F84816FCB8FCA43AFE000FE001A800
+7CED00F8C71500B3B3A40107B512C049804980A26D5C6D5C2E3D7EBC33>84
+D<273FFFE001B5FC486D481480B56C4814C0A26C496C14806C496C1400D801FCC7EA0FE0
+B3B3A36D141F00005EA26D143F6D5DA26D6C49C7FC6E5B6D6C485AECF00390390FFC0FFC
+6DB55A6D5C6D5C6D6C1380DA1FFEC8FCEC07F8323E80BC33>I<007FB512C0B612E0A415
+C048C8FCB3B3B3ABB612C015E0A46C14C01B4D6CC433>91 D<007FB512C0B612E0A47EC7
+120FB3B3B3AB007FB5FCB6FCA46C14C01B4D7DC433>93 D<007FB612FEA2B8FCA36C15FE
+A228077B7D33>95 D<EB1FFC90B57E000314E048804814FC48809038F007FFEBE0016E7F
+153F6C48806C48131FC87F150FA5EC0FFF49B5FC131F137F48B6FC0007140F4813C0381F
+FC00EA3FF0EA7FC05B48C7FC5AA56C141F7E6D137FD83FE0497ED9F807EBFFF06CB712F8
+7E6C14F36C14C1C69138003FF0D91FF090C7FC2D2E7BAC33>97 D<ECFFF0010713FE011F
+EBFF804914C04914E048B612F048EBC01F9038FE000F485A485A4848EB07E049EB03C048
+4890C7FC5BA2127F90C9FCA25A5AA97E7EA27F003FEC01F06DEB03F86C7E6D13076C6C14
+F06C6C130F01FFEB1FE06CEBE07F6C90B512C06C1580013F14006D13FC01075B010013C0
+252E79AC33>99 D<ED7FF84B7E5CA280157F1501ABEB01FF010713C1011F13F1017F13F9
+90B6FC5A4813813907FE003FD80FF8131F49130F48481307491303123F491301127F90C7
+FCA25A5AA97E7E15037F123F6D1307A26C6C130F6D131F6C6C133F6C6C137F2603FF81B5
+12F091B612F8C602FD13FC6D13F96D01E113F8010F018013F0D901FEC8FC2E3E7DBC33>
+I<ECFF80010713F0011F13FC497F90B6FC48158048018013C03A07FE003FE001F8EB0FF0
+48481307484814F8491303003F15FC491301127F90C7FC16FE15005A5AB7FCA516FC48C9
+FC7E7EA36C7E167C6C6C14FE7F6C7E6D13016C6CEB03FC6CB4130F6C9038C03FF86C90B5
+12F06D14E06D14C0010F1400010313FC9038007FE0272E7BAC33>I<ED3FE0913801FFFC
+020713FE141F4A13FF5CECFFC015004948137E4A133C010314005CA8003FB612F84815FC
+B7FCA36C15F8260003F8C7FCB3AD003FB612804815C0A46C1580283E7DBD33>I<EA3FFC
+487E12FFA2127F123F1200AB4AB4FC020713C0021F13F0027F7F91B5FC90B67EED07FEEC
+F801ECF0004A7F4A7F5CA291C7FCA35BB3A43B3FFFF80FFFFC486D4813FEB56C4813FFA2
+6C496C13FE6C496C13FC303D7FBC33>104 D<14E0EB03F8A2497EA36D5AA2EB00E091C8
+FCAA383FFFF8487FA47EEA0001B3AD007FB612C0B712E016F0A216E06C15C0243E78BD33
+>I<EA7FF8487EA4127F1200AC4AB512C04A14E04A14F0A26E14E06E14C09139000FF000
+4B5A4B5A4B5A4BC7FC4A5A4A5A4A5A4A5A4A5A4A5A4A5A4A7E01FD7F90B5FC81ECF3F8EC
+E3FC14C1EC80FEEC007F5B496D7E6F7E82150F6F7E6F7E8215016F7E3B7FFFF80FFFF0B5
+6C4813F817FCA217F86C496C13F02E3D7EBC33>107 D<02FC137E3B7FC3FF01FF80D8FF
+EF01877F90B500CF7F15DF92B57E6C010F13872607FE07130301FC01FE7F9039F803FC01
+A201F013F8A401E013F0B3A53C7FFE0FFF07FF80B548018F13C0A46C486C01071380322C
+80AB33>109 D<4AB4FC263FFC0713C0267FFE1F13F000FF017F7F91B5FC6CB67E6CEC07
+FEC6EBF801ECF0004A7F4A7F5CA291C7FCA35BB3A43B3FFFF80FFFFC486D4813FEB56C48
+13FFA26C496C13FE6C496C13FC302C7FAB33>I<EB01FE90380FFFC0013F13F0497F90B5
+7E488048EB03FF2607FC0013804848EB7FC049133F4848EB1FE049130F4848EB07F0A200
+7F15F890C71203A300FEEC01FCAA6C14036C15F8A26D1307003F15F06D130FA26C6CEB1F
+E06D133F6C6CEB7FC06C6CEBFF802603FF0313006CEBFFFE6C5C6D5B6D5B010F13C0D901
+FEC7FC262E7AAC33>I<EC01FE3A3FFC0FFFC0486C4813F000FF017F7F91B512FE6CB7FC
+6CEBFE07C6D9F800138002E0EB7FC04AEB3FE04A131FEE0FF091C7FC16074915F81603A2
+17FC1601A9160317F8A26D140717F06E130F17E06E131FEE3FC06E137F9139F801FF80DA
+FE07130091B55A495C6E5B6E13E0020F1380DA03FEC7FC91C9FCAF383FFFF8487FB57EA2
+6C5B6C5B2E427FAB33>I<ED03FE3B7FFF801FFF80B5D8C07F13E002C1B5FC02C314F014
+C76C9038CFFE0F39001FDFF09139FFC007E092388003C092C8FC5C5C5CA25CA25CA35CB2
+007FB512FEB7FCA46C5C2C2C7DAB33>114 D<90381FFE0F90B5EA8F80000314FF120F5A
+5AEBF007387F800190C7FC00FE147F5A153FA37E007FEC1F0001C090C7FCEA3FF8EBFFC0
+6C13FF6C14E0000314F8C680011F13FF01001480020713C0EC007FED1FE0007C140F00FE
+EC07F01503A27EA27F15076D14E06D130F6DEB3FC09038FE01FF90B61280160000FD5C00
+FC14F8D8F83F13E0D8780790C7FC242E79AC33>I<EB03C0497E130FAA003FB612FC4881
+B7FCA36C5D26000FE0C8FCB3A3161FEE3F80A5167F6E140001075C6E5A9138FE07FE6DB5
+5A6D5C6D5C6E5B021F1380DA07FCC7FC29387EB633>I<D83FFCEB1FFE486C497E00FF5C
+A2007F80003F800000EC007FB3A75EA25DA26D5B90387F800FDAE03F13FC6DB612FE17FF
+6D806D01FE13FE01039038F83FFC010001C0C7FC302C7FAA33>I<3B3FFFC07FFF80486D
+B512C0B500F114E0A26C01E014C06C496C13803B00FE000FE000017F495AEB3F804B5A6D
+6C48C7FC90380FE07E903807F0FEECF1FC903803FBF8EB01FF6D5B5D6E5A143F6E5A143F
+814A7E14FF903801FBF0ECF9F8903803F1FCEB07E0157E90380FC07F011F6D7E90383F80
+1F02007F496D7E01FE6D7E484813033B7FFFC03FFFE0B56C4813F0A46C496C13E02C2B7D
+AA33>120 D<ED07FEED7FFF4AB5FC14075C4A13FE91383FFE0015E0EC7F8092C7FCB3A4
+5C495A1303EB1FFCEA3FFFB55A14E05C8014F8003F7FEA001FEB03FE13016D7E80B3A481
+EC3FE015FE91381FFFFE6E13FF8014016E7EED07FE284D7BC433>123
+D<EA7FF0B5FC14C014F0806C7F38003FFE1303EB00FF80B3A4816E7E81EC1FFCEDFFFC6E
+13FF1403805C140F4A13FCEDFC00EC3FE05D4A5A92C7FCB3A45CEB03FE133F387FFFFCB5
+5A5C14C091C8FCEA7FF0284D7BC433>125 D E
+%EndDVIPSBitmapFont
+%DVIPSBitmapFont: Fb cmbx12 12 22
+/Fb 22 118 df<ED0FFF4AB512C0020F14F0027F80903A01FFF803FC499038C000FE010F
+EB00034948497E49485B5C495A4C138001FF6E13005CA3705AEE01F893C8FCA74BB51280
+B9FCA5C69038E00003B3B0007FD9FFC1B6FCA538467EC53E>12 D<B612F8A91D097F9A25
+>45 D<EA07C0EA1FF0EA3FF8EA7FFCEAFFFEA7EA7FFCEA3FF8EA1FF0EA07C00F0F788E1F
+>I<EE01C0EE03E01607A2160F17C0161F1780A2163F17005E167EA216FE5E15015EA215
+035EA215075E150F5EA2151F5E153F93C7FCA25D157E15FE5DA214015D14035DA214075D
+140F5DA2141F5D143F92C8FCA25C147EA214FE5C13015CA213035C13075CA2130F5C131F
+5CA2133F91C9FC5B137EA213FE5B12015BA212035BA212075B120F5BA2121F5B123F90CA
+FCA25A127E12FE5AA25A12782B647ACA38>I<EA07C0EA1FF0EA3FF8EA7FFCEAFFFEA7EA
+7FFCEA3FF8EA1FF0EA07C0C7FCAEEA07C0EA1FF0EA3FF8EA7FFCEAFFFEA7EA7FFCEA3FF8
+EA1FF0EA07C00F2C78AB1F>58 D<903801FFE0011F13FE017F6D7E48B612E03A03FE007F
+F84848EB1FFC6D6D7E486C6D7EA26F7FA36F7F6C5A6C5AEA00F090C7FCA40203B5FC91B6
+FC1307013F13F19038FFFC01000313E0000F1380381FFE00485A5B127F5B12FF5BA35DA2
+6D5B6C6C5B4B13F0D83FFE013EEBFFC03A1FFF80FC7F0007EBFFF86CECE01FC66CEB8007
+D90FFCC9FC322F7DAD36>97 D<EB7FC0B5FCA512037EB1ED0FF892B57E02C314E002CF14
+F89139DFC03FFC9139FF000FFE02FCEB03FF4A6D13804A15C04A6D13E05CEF7FF0A218F8
+173FA318FCAC18F8A2177F18F0A3EFFFE06E15C06E5B6E491380027C491300496C495A90
+3AFC1FC07FFC496CB512F0D9F00314C049C691C7FCC8EA1FF036467DC43E>I<EC3FFC49
+B512C0010F14F0013F14FC90397FF003FE9039FFC001FF0003495A48494813805B120F48
+5AA2485A6F1300007F6E5AED00784991C7FCA212FFAC6C7EA3123F6DEC03C0A26C6C1407
+000F16806D140F6C6DEB1F006C6D133E6C01F05B3A007FFC03F86DB55A010F14C0010391
+C7FC9038003FF82A2F7CAD32>I<EE03FEED07FFA5ED001F160FB1EC3FE0903803FFFC01
+0FEBFF8F013F14CF9039FFF807FF48EBC00148903880007F4890C7123F4848141F49140F
+121F485AA3127F5BA212FFAC127FA37F123FA26C6C141FA26C6C143F0007157F6C6C91B5
+FC6CD9C00314FC6C9038F01FEF6DB5128F011FEBFE0F010713F89026007FC0EBF8003646
+7CC43E>I<EC3FF80103B57E010F14E0013F8090397FF83FF89039FFC007FC48496C7E48
+496C7E48486D1380485A001FED7FC05B003FED3FE0A2127F5B17F0161F12FFA290B7FCA4
+01F0C9FCA5127FA27FA2123F17F06C7E16016C6C15E06C6C14036C6DEB07C06C6DEB0F80
+6C01F0EB3F0090397FFE01FE011FB55A010714F0010114C09026001FFEC7FC2C2F7DAD33
+>I<EB7FC0B5FCA512037EB1ED07FE92383FFF8092B512E002C114F89139C7F03FFC9138
+CF801F9139DF000FFE14DE14FC4A6D7E5CA25CA35CB3A7B60083B512FEA537457CC43E>
+104 D<137C48B4FC4813804813C0A24813E0A56C13C0A26C13806C1300EA007C90C7FCAA
+EB7FC0EA7FFFA512037EB3AFB6FCA518467CC520>I<EC03E0EC0FF8EC1FFCEC3FFEA2EC
+7FFFA5EC3FFEA2EC1FFCEC0FF8EC03E091C7FCAAEC01FF0103B5FCA5EB000F80B3B3A7EA
+1F80EA3FC0EA7FE0EAFFF0EC0FFEA215FC141F01E013F8007FEB3FF0393FC0FFE06CB512
+806C1400000313FCC613C0205A86C522>I<EB7FC0B5FCA512037EB3B3B3A3B61280A519
+457CC420>108 D<90397F8007FEB590383FFF8092B512E0028114F8913987F03FFC9138
+8F801F000390399F000FFE6C139E14BC02F86D7E5CA25CA35CB3A7B60083B512FEA5372D
+7CAC3E>110 D<EC1FFC49B512C0010714F0011F14FC90397FF80FFF9026FFC0017F4849
+6C7F4848C7EA3FE000078248486E7E49140F001F82A2003F82491407007F82A400FF1780
+AA007F1700A46C6C4A5AA2001F5E6D141F000F5E6C6C4A5AA26C6C6CEBFFE06C6D485B27
+007FF80F90C7FC6DB55A010F14F8010114C09026001FFCC8FC312F7DAD38>I<90397FC0
+0FF8B590B57E02C314E002CF14F89139DFC03FFC9139FF001FFE000301FCEB07FF6C496D
+13804A15C04A6D13E05C7013F0A2EF7FF8A4EF3FFCACEF7FF8A318F017FFA24C13E06E15
+C06E5B6E4913806E4913006E495A9139DFC07FFC02CFB512F002C314C002C091C7FCED1F
+F092C9FCADB67EA536407DAC3E>I<DA3FE0131E902603FFFC133E010F01FF137E013F14
+80903AFFF80FE0FE489038E003F148EBC0014890388000FB4890C7127F49143F001F151F
+485A160F5B127FA3485AAC6C7EA46C7EA26C6C141F163F6C6C147F6C15FF6C6D5A6C9038
+E003EF6C9038F01FCF6DB5128F011FEBFE0F010313F89038007FC091C7FCAD0307B512FC
+A536407CAC3B>I<90387F807FB53881FFE0028313F0028F13F8ED8FFC91389F1FFE0003
+13BE6C13BC14F8A214F0ED0FFC9138E007F8ED01E092C7FCA35CB3A5B612E0A5272D7DAC
+2E>I<90391FFC038090B51287000314FF120F381FF003383FC00049133F48C7121F127E
+00FE140FA215077EA27F01E090C7FC13FE387FFFF014FF6C14C015F06C14FC6C80000380
+6C15806C7E010F14C0EB003F020313E0140000F0143FA26C141F150FA27EA26C15C06C14
+1FA26DEB3F8001E0EB7F009038F803FE90B55A00FC5CD8F03F13E026E007FEC7FC232F7C
+AD2C>I<EB01E0A51303A41307A2130FA2131FA2133F137F13FF1203000F90B51280B7FC
+A4C601E0C7FCB3A3ED01E0A9150302F013C0137F150790393FF80F8090391FFC1F006DB5
+FC6D13FC01015B9038003FE023407EBE2C>I<D97FC049B4FCB50103B5FCA50003EC000F
+6C81B3A85EA25EA25E7E6E491380017FD901F713FE9138F807E76DB512C7010F14070103
+13FE9026007FF0EBFC00372E7CAC3E>I E
+%EndDVIPSBitmapFont
+%DVIPSBitmapFont: Fc cmbx12 14.4 22
+/Fc 22 121 df<EA07F0487E487E487E487EB51280A76C13006C5A6C5A6C5A6C5A111176
+9025>46 D<157815FC14031407141F14FF130F0007B5FCB6FCA2147F13F0EAF800C7FCB3
+B3B3A6007FB712FEA52F4E76CD43>49 D<EC3FFE0103B512E0010F14FC013F14FF90B712
+C048D9C07F7F2703FE000F13F8D807F801037FD80FE06D7F48486D7F48488001F0168048
+6C6E13C07F486C6E13E07FA27013F0A56C5AA26C5AEA0FF0EA03C0C914E05EA218C05E18
+80A24C13005F4C5A4B5B5F4B5B5F4B5B4B90C7FC4B5A5E4B5AED7FE04B5A4A5B4A48C8FC
+4A5A5D4A48EB01F04A5AEC3F804AC7FC02FEEC03E0495A495A495A495AD91F80140749C8
+FC013E150F017FB7FC90B812C05A5A5A5A5A5A5AB9FC1880A4344E79CD43>I<EA07F048
+7E487E487E487EB51280A76C13006C5A6C5A6C5A6C5AC8FCB3EA07F0487E487E487E487E
+B51280A76C13006C5A6C5A6C5A6C5A113576B425>58 D<932601FFFCEC01C0047FD9FFC0
+13030307B600F81307033F03FE131F92B8EA803F0203DAE003EBC07F020F01FCC7383FF0
+FF023F01E0EC0FF94A01800203B5FC494848C9FC4901F882494982494982494982494982
+4990CA7E494883A2484983485B1B7F485B481A3FA24849181FA3485B1B0FA25AA298C7FC
+5CA2B5FCAE7EA280A2F307C07EA36C7FA21B0F6C6D1980A26C1A1F6C7F1C006C6D606C6D
+187EA26D6C606D6D4C5A6D6D16036D6D4C5A6D6D4C5A6D01FC4C5A6D6DEE7F806D6C6C6C
+4BC7FC6E01E0EC07FE020F01FEEC1FF80203903AFFE001FFF0020091B612C0033F93C8FC
+030715FCDB007F14E0040101FCC9FC525479D261>67 D<B600FC93B7FC8181A282D80007
+6E9239003FFC0070EE07E08282A28202EF7F02E77F02E380A202E18002E0806F7F6F7F6F
+7FA26F7F6F7F6F806F80A26F80707F707F707F707FA2707F7080708070808583717F717F
+717F717FA27114807114C07114E07213F07213F8A27213FC7213FE7213FF721487A27214
+C77214E77313F77313FF85A285858585A28586868686A286868686A2D93FFC187FB7173F
+1B1F1B0F1B07755A60527CD169>78 D<91260FFF80130791B500F85B010702FF5B011FED
+C03F49EDF07F9026FFFC006D5A4801E0EB0FFD4801800101B5FC4848C87E48488149150F
+001F824981123F4981007F82A28412FF84A27FA26D82A27F7F6D93C7FC14C06C13F014FF
+15F86CECFF8016FC6CEDFFC017F06C16FC6C16FF6C17C06C836C836D826D82010F821303
+010082021F16801400030F15C0ED007F040714E01600173F050F13F08383A200788200F8
+82A3187FA27EA219E07EA26CEFFFC0A27F6D4B13806D17006D5D01FC4B5A01FF4B5A02C0
+4A5A02F8EC7FF0903B1FFFC003FFE0486C90B65AD8FC0393C7FC48C66C14FC48010F14F0
+48D9007F90C8FC3C5479D24B>83 D<EC7FFF0107B512F0013F14FE90B77E48D9E00F7F27
+03FE000113F0486C6D7F6EEB3FFC48826E131F83707FA36C496D7FA26C90C7FC6C5AC9FC
+A6037FB5FC020FB6FC91B7FC01071487013FEBF0074913803901FFFC004813F0485B485B
+485B4890C7FC5A5BA2485AA45EA26D5C007F151D163D6C6C02797F6C6D01F113F86C9026
+C003E1EBFFE06C9026F81FC014F06C90B5487EC6ED001F011F01FC010713E0010101E090
+C8FC3C387CB641>97 D<913801FFF8021FEBFF8091B612F0010315FC010F9038C00FFE90
+3A1FFE0001FFD97FFC491380D9FFF05B4817C048495B5C5A485BA2486F138091C7FC486F
+1300705A4892C8FC5BA312FFAD127F7FA27EA2EF03E06C7F17076C6D15C07E6E140F6CEE
+1F806C6DEC3F006C6D147ED97FFE5C6D6CEB03F8010F9038E01FF0010390B55A01001580
+023F49C7FC020113E033387CB63C>99 D<4DB47E0407B5FCA5EE001F1707B3A4913801FF
+E0021F13FC91B6FC010315C7010F9038E03FE74990380007F7D97FFC0101B5FC49487F48
+49143F484980485B83485B5A91C8FC5AA3485AA412FFAC127FA36C7EA37EA26C7F5F6C6D
+5C7E6C6D5C6C6D49B5FC6D6C4914E0D93FFED90FEFEBFF80903A0FFFC07FCF6D90B5128F
+0101ECFE0FD9003F13F8020301C049C7FC41547CD24B>I<913803FFC0023F13FC49B6FC
+010715C04901817F903A3FFC007FF849486D7E49486D7E4849130F48496D7E4817804849
+7F18C0488191C7FC4817E0A248815B18F0A212FFA490B8FCA318E049CAFCA6127FA27F7E
+A218E06CEE01F06E14037E6C6DEC07E0A26C6DEC0FC06C6D141F6C6DEC3F806D6CECFF00
+D91FFEEB03FE903A0FFFC03FF8010390B55A010015C0021F49C7FC020113F034387CB63D
+>I<DA3FFF14FF0103B5D8F00713C0010FDAFC1F13E0013FECFF7F90267FFC0F9038FF9F
+F09026FFE001EBF83F48496C13E0484990387FF01F4890C7D83FF813E0489338FC0FC0F0
+078048486E6CC7FCA2003F82A9001F5EA26C6C4A5AA26C5E6C6D495A6C6D495A6C6D485B
+DAFC0F5B4890B6C8FCD803EF14FC01C314F02607C03F90C9FC91CBFCA2120FA37FA213F8
+13FE90B7FC6C16F817FF18C06C836C836C836D828448B9FC12074848C700031480D81FF8
+EC003F4848150748486F13C083485A83A56D5D007F18806D5D003F18006C6C4B5AD80FFE
+ED1FFC6C6C6CEC7FF86C01E049485A6C01FE011F5B6C6CB71280010F03FCC7FC010115E0
+D9000F01FCC8FC3C4F7CB543>103 D<EB3FF0B5FCA51203C6FCB3A4EE1FFC93B512C003
+0314F0030F8092391FE07FFC92393F001FFE037C8003F07FDAF1E081ECF3C0DAF7807F85
+02FFC7FC5CA25CA45CB3ACB6D8F807B612C0A542537BD24B>I<137F497E000313E0487F
+A2487FA76C5BA26C5BC613806DC7FC90C8FCADEB3FF0B5FCA512017EB3B3A6B612E0A51B
+547BD325>I<D93FF0D91FFCEDFFE0B591B500C0010713FE030302F0011F6D7E030F6E01
+7F8092271FE07FFCD9FF037F922A3F001FFE01F8007F0003027C9126FF03E080C602F06D
+D90780137FDAF1E0038FC77FDAF3C0159EDAF7806D01BC143F07FC8102FFC75C4A5EA24A
+5EA44A5EB3ACB6D8F807B6D8C03FB512FEA567367BB570>109 D<D93FF0EB1FFCB591B5
+12C0030314F0030F8092391FE07FFC92393F001FFE0003027C80C602F07FDAF1E081ECF3
+C0DAF7807F8502FFC7FC5CA25CA45CB3ACB6D8F807B612C0A542367BB54B>I<913801FF
+E0021F13FE91B612C0010315F0010F9038807FFC903A1FFC000FFED97FF86D6C7E49486D
+7F48496D7F48496D7F4A147F48834890C86C7EA24883A248486F7EA3007F1880A400FF18
+C0AC007F1880A3003F18006D5DA26C5FA26C5F6E147F6C5F6C6D4A5A6C6D495B6C6D495B
+6D6C495BD93FFE011F90C7FC903A0FFF807FFC6D90B55A010015C0023F91C8FC020113E0
+3A387CB643>I<90397FE003FEB590380FFF80033F13E04B13F09238FE1FF89139E1F83F
+FC0003D9E3E013FEC6ECC07FECE78014EF150014EE02FEEB3FFC5CEE1FF8EE0FF04A90C7
+FCA55CB3AAB612FCA52F367CB537>114 D<903903FFF00F013FEBFE1F90B7FC120348EB
+003FD80FF81307D81FE0130148487F4980127F90C87EA24881A27FA27F01F091C7FC13FC
+EBFFC06C13FF15F86C14FF16C06C15F06C816C816C81C681013F1580010F15C013000207
+14E0EC003F030713F015010078EC007F00F8153F161F7E160FA27E17E07E6D141F17C07F
+6DEC3F8001F8EC7F0001FEEB01FE9039FFC00FFC6DB55AD8FC1F14E0D8F807148048C601
+F8C7FC2C387CB635>I<143EA6147EA414FEA21301A313031307A2130F131F133F13FF5A
+000F90B6FCB8FCA426003FFEC8FCB3A9EE07C0AB011FEC0F8080A26DEC1F0015806DEBC0
+3E6DEBF0FC6DEBFFF86D6C5B021F5B020313802A4D7ECB34>I<D93FF8913801FFC0B502
+07B5FCA50003ED001FC61607B3AE5FA35FA2017F5D173B177B6D6C14F3DC01E313F06D6C
+D907C3EBFFC0903A0FFFC03F836D90B51203010114FE6D6C13F8020701E091C7FC42377B
+B54B>I<007FB500F090387FFFFEA5C66C48C7000F90C7FC6D6CEC07F86D6D5C6D6D495A
+6D4B5A6F495A6D6D91C8FC6D6D137E6D6D5B91387FFE014C5A6E6C485A6EEB8FE06EEBCF
+C06EEBFF806E91C9FCA26E5B6E5B6F7E6F7EA26F7F834B7F4B7F92B5FCDA01FD7F03F87F
+4A486C7E4A486C7E020F7FDA1FC0804A486C7F4A486C7F02FE6D7F4A6D7F495A49486D7F
+01076F7E49486E7E49486E7FEBFFF0B500FE49B612C0A542357EB447>120
+D E
+%EndDVIPSBitmapFont
+%DVIPSBitmapFont: Fd cmti12 12 35
+/Fd 35 122 df<4CB414FC040F9039C003FF80933B3F81F00783C0933B7C00781F01E04C
+9038F83F03923C01F001FC3E07F003030103EB7E0F922607E007EB7C1F19FCDB0FC001F8
+14E0943A03F0F80FC0DD01E1EB0780031FD9000190C7FC5E180361153F93C7FCA2180761
+5D157EA2180F6115FE91B912F0A3DA00FCC7D81F80C7FC1401A25D183F96C8FCA214035D
+A260187E14075DA218FE60140F5DA2170160141F5DA2170360143F92C7FCA21707605C14
+7EA2170F6014FE5CA24D5AA2495A95C9FC5F5C0103153E177E001CEBE038007F02FE137C
+26FF07E114FC02C15C4C5AEB0F8100FE903901FC03E0D8F81F9038F007C03B701E00E00F
+80D8783CD9F83ECAFCD81FF0EB3FF8D807C0EB0FE04C5A83C53C>11
+D<EF7FF80407B5FC93391FC00FC093393E0001E004FCEB00F04B4813014B4813075E0307
+140FA24B5A19E0031FEC03804C90C7FCA3153F93C9FCA45D157EA415FE91B8FCA260DA00
+FCC7127E020115FE4B5CA317016014035D170360A214074B130760A3020F140F4B5CA317
+1F021F5D5DA2053F13E01801023F16C092C7FCA2EF7F03057E13805C027E15071900173E
+180E02FEEC1E1E4AEC1F1CEF07F8EF01E094C8FC495AA35C1303A2001C5B127FEAFF075C
+A2495A00FE90CBFCEAF81FEA701EEA783CEA1FF0EA07C03C5A83C537>I<160E161EA316
+3EA2163CA2167CA21678A216F8A25EA21501A25EA21503A25EA21507A25EA2007FB912E0
+BAFCA27EC8001FC9FCA2151EA2153EA2153CA2157CA21578A215F8A25DA21401A25DA214
+03A25DA21407A25D14033B3C73B64B>43 D<007FB5FCB6FCA214FEA21805789723>45
+D<120FEA3FC0127FA212FFA31380EA7F00123C0A0A76891E>I<F001C018031807A2F00F
+80A2F01F00A2183E187E187C60A24D5AA24D5AA24D5A170F604DC7FCA2173EA25F17FC5F
+4C5AA24C5AA24C5AA24C5A161F94C8FC163EA25EA25E15015E4B5AA24B5AA24B5AA24BC9
+FC5D153E5DA25DA24A5A14035D4A5AA24A5AA24ACAFCA2143E147E147C5CA2495AA2495A
+13075C495AA249CBFCA2133EA25B13FC5B485AA2485AA2485A120F5B48CCFCA2123EA25A
+A25AA212703A647FCA32>I<EF03801707A24D7EA2171FA2173F177FA217FFA25EA2EE03
+BF1607173F160F160E161C841638171F167016F016E0ED01C0A2ED0380A2ED0700A2150E
+151E151C5D845D170F5D14015D14035D4AC7FC92B6FC5CA2021CC7120F143C14385CA24A
+81A249481407A2495A130791C8FC130E131EA25B137C13FC00014C7ED807FE151FB500E0
+0107B512F8A219F03D477BC648>65 D<DC0FF8130393B513070307ECC00F923A1FF803E0
+1F923A7FC000F81E4BC7EA7C3EDA03FCEC3C7EDA0FF0EC1EFE4A48EC0FFC4A4814074AC8
+FC02FE1503494816F8130349481501495A494816F0495A137F5C01FF17E04890C9FCA248
+5A19C0485AA2485A95C7FC121F5BA2123F5BA3127F5BA4485AA41838A218781870A218F0
+007F5F1701601703003F5F17076D4BC7FC001F160E171E6C6C5D6D5D00075E6C6C4A5A6D
+EC07C06C6C4A5AD8007F023EC8FCD93FC013FC90391FF807F00107B512C0010191C9FC90
+38001FF0404872C546>67 D<91B56C49B512E0A28202009239000FFC00F107F0706E5A4A
+5F15DF705D1907EC03CFDB8FF892C7FCA203875D02077F0303150EA270141EEC0F01020E
+161C826F153C141E021C6E1338167F1978023C800238013F1470A27113F00278131F0270
+5E83040F130102F014F84A5E1607EFFC0313014A01035C17FE1807010314014A02FF90C8
+FCA2705B0107168F91C8138E177F18DE5B010EED3FDC18FCA2011E151F011C5EA2170F13
+3C01386F5A1378A201F81503486C5EEA07FEB500F01401A2604B447AC348>78
+D<EE1FF84BB5FC923907F01FC092391F8003F092397E0001F8DA01F86D7EDA03E0147EDA
+0FC0804A48EC1F804AC813C0027E150F4A16E049481507494816F01307495A494816F801
+3F16035C137F49C9FC4917FC120112035B1207491607120FA25B121F19F849160F123FA3
+4848EE1FF0A3183F19E0485A19C0187FA2F0FF80A219005F604D5AA2007F4C5A4D5AA24D
+5A003F5F4D5A6D4BC7FC001F5E4C5A6C6C5DEE03F06C6C4A5A0003ED1FC06C6C4A5A6C6C
+027EC8FC017EEB01F890393F8007F090390FE03F80902603FFFEC9FC9038007FE03E4872
+C54B>I<91B712F018FEF0FF800201903980007FE06E90C7EA1FF04AED07F818034B15FC
+F001FE1403A24B15FFA21407A25DA2140FF003FE5DA2021F16FC18074B15F8180F023F16
+F0F01FE04B15C0F03F80027FED7F0018FE4BEB03FCEF0FF002FFEC7FC092B6C7FC17F892
+CAFC5BA25CA21303A25CA21307A25CA2130FA25CA2131FA25CA2133FA25CA2137FA25C49
+7EB67EA340447AC342>I<DB03FE130C92390FFF801C037FEBE03C9238FE03F8913A03F0
+007C7C4A48EB3EF84A48131F4A48130F4AC7FC027EEC07F05C1703495A18E0495AA21307
+4A15C0A3130F1880A28094C7FCA280806D7EECFFE015FC6DEBFF806D14F016FC6D14FF02
+3F80020F801403DA003F7F150703007F163F161F160FA21607A3120716031607A2485EA2
+120E160F001E5EA2001F4B5AA2484BC7FC6D143E167E6D5C007F4A5A6D495AD87CF0495A
+D8787CEB1F8027F03F807FC8FC90381FFFFCD8E00713F039C0007F80364879C537>83
+D<48B912F85AA2913B0007FC001FF0D807F84A130701E0010F140349160148485C90C715
+00A2001E021F15E05E121C123C0038143F4C1301007818C0127000F0147F485DA3C800FF
+91C7FC93C9FCA35C5DA314035DA314075DA3140F5DA3141F5DA3143F5DA3147F5DA314FF
+92CAFCA35B5CA21303A21307497E007FB612C0A25E3D446FC346>I<EC1F80EC7FE09039
+01F07070903907C039F890380F801D90381F001F013E6D5A137E5B484813075E485A1207
+49130F000F5DA2485A151F003F5D5BA2153F007F92C7FC90C7FCA25D157E12FEA29238FE
+0380EDFC071700A2007E13015E913803F80E1407003E010F131E161C6C131C02385B3A0F
+80F078783A07C3E07C703A01FF801FE03A007E000780292D76AB32>97
+D<EB0FE0EA07FFA338001FC0130F131FA25CA3133F91C8FCA35B137EA313FE5BA312015B
+EC1F80EC7FE03903F9E0F89038F3C07C9038F7003E13FE48487F5BA2491480485AA25BA2
+121F5BA2153F123F90C7FCA2157F481500127EA25D5D5AA24A5AA24A5AA2007C5C4A5A14
+0F5D4A5A003C49C7FC003E137E001E5B6C485A380783E03803FF80C648C8FC214676C42D
+>I<EC0FE0EC7FF8903801F81E903807E00F90390F80078090381F0003017E14C049131F
+0001143F5B4848EB7F801207485AED3E00484890C7FCA2485AA2127F90C9FCA35A5AA45A
+A5ED0180ED03C0ED0780A2007CEC0F00007E141E003E147C15F06CEB03E0390F800F8026
+07C07EC7FC3801FFF838007FC0222D75AB2D>I<EE07F0ED03FFA39238000FE01607160F
+A217C0A2161FA21780A2163FA21700A25EA2167EA216FEA25EEC1F80EC7FE1903801F071
+903907C039F890380F801D90381F001F013E130F017E5C5B48481307A248485C12074913
+0F120F5E485A151F123F495CA2153F127F90C790C7FCA25DA200FE147EA29238FE038016
+0703FC1300A2007E13015E913803F80E1407003E010F131E161C6C131C02385B3A0F80F0
+78783A07C3E07C703A01FF801FE03A007E0007802C4676C432>I<EC0FE0EC7FF8903801
+F83E903807C00F90391F800780EB3F00017E14C0491303485A48481307000715805B000F
+140F484814005D4848133E15FCEC07F0007FEBFFC0D9FFFEC7FC14C090C9FC5A5AA55AA4
+ED0180ED03C0007CEC0780A2007EEC0F00003E141E157C6C14F06CEB03E03907800F8026
+03C07EC7FC3801FFF838003FC0222D75AB2D>I<EE0F80EE3FE0EEF870923801F0389238
+03E0F8923807E1FC16C3ED0FC7A2EE87F892381F83F0EE81E0EE8000153F93C7FCA45D15
+7EA415FE5DA349B512FEA390260001F8C7FCA314035DA414075DA4140F5DA4141F5DA414
+3F92C8FCA55C147EA314FE5CA413015CA4495AA35C1307121C007F5B12FF495AA291C9FC
+485AEAF81E485AEA7878EA1FF0EA07C02E5A83C51E>I<15FCEC03FF91390F8383809139
+3E01CFC091387C00EF4A13FF4948137F010315804948133F495A131F4A1400133F91C75A
+5B167E13FE16FE1201495CA215011203495CA21503A2495CA21507A25EA2150F151F5E00
+01143F157F6C6C13FF913801DF8090387C039F90383E0F3FEB0FFCD903F090C7FC90C7FC
+5DA2157EA215FEA25DA2001C495A127F48495A14074A5A485C023FC8FC00F8137E387C01
+F8381FFFE0000390C9FC2A407BAB2D>I<14FE137FA3EB01FC13001301A25CA21303A25C
+A21307A25CA2130FA25CA2131FA25C157F90393F83FFC091388F81F091381E00F802387F
+4948137C5C4A137EA2495A91C7FCA25B484814FE5E5BA2000314015E5BA2000714035E5B
+1507000F5DA249130F5E001F1678031F1370491480A2003F023F13F0EE00E090C7FC1601
+48023E13C01603007E1680EE070000FEEC1E0FED1F1E48EC0FF80038EC03E02D467AC432
+>I<143C147E14FE1301A3EB00FC14701400AE137C48B4FC3803C780380703C0000F13E0
+120E121C13071238A21278EA700F14C0131F00F0138012E0EA003F1400A25B137EA213FE
+5B12015BA212035B141E0007131C13E0A2000F133CEBC038A21478EB807014F014E0EB81
+C0EA0783EBC7803803FE00EA00F8174378C11E>I<14FE137FA3EB01FC13001301A25CA2
+1303A25CA21307A25CA2130FA25CA2131FA25C167E013F49B4FC92380783C09138000E07
+ED3C1F491370ED603F017E13E0EC01C09026FE03801380913907000E00D9FC0E90C7FC5C
+00015B5C495AEBF9C03803FB8001FFC9FCA214F03807F3FCEBF07F9038E01FC06E7E000F
+130781EBC003A2001F150FA20180140EA2003F151E161C010013E0A2485DA2007E157816
+7000FE01015B15F1489038007F800038021FC7FC2A467AC42D>107
+D<EB03F8EA01FFA3380007F013031307A214E0A2130FA214C0A2131FA21480A2133FA214
+00A25BA2137EA213FEA25BA21201A25BA21203A25BA21207A25BA2120FA25BA2121FA25B
+A2123FA290C7FCA2387F01C01303007E1380A2130700FE130012FCA25B130EEA7C1E131C
+EA3C3CEA3E786C5AEA07C0154678C419>I<D801F0D90FE0EB07F0D803FCD97FF8EB3FFC
+28071E01F03EEBF81F3E0E1F03C01F01E00F80271E0F8700D983807F001C018E90390F87
+0007003C019C148E003801B802DC8002F814FC26781FF05C0070495CA24A5C00F0494948
+130FD8E03F6091C75B1200043F141F4960017E92C7FCA24C143F01FE95C7FC49147E6104
+FE147E1201494A14FE610301EE0780000305011400494A14F8A2030302035B0007F0F00E
+495C1A1E0307EDE01C000F193C494A153862030F020113F0001FF0F1E0494A903800FF80
+0007C7D80380023EC7FC492D78AB50>I<D801F0EB0FE0D803FCEB7FF83A071E01F03E3A
+0E0F03C01F001ED987001380001C018E130F003C139C003801B814C014F838781FF00070
+5BA25C00F049131FD8E03F158091C7FC1200163F491500137EA25E01FE147E5B16FE5E12
+014913015E170F00030203130E4914F0A20307131E0007EDE01C5B173CEEC038000F1678
+49157017E0ED03C1001FEDE3C049903801FF000007C8127C302D78AB37>I<EC0FE0EC7F
+FC903801F83E903907E00F8090390F8007C0EB1F00017EEB03E04914F0A2484813014848
+14F81207485AA2485AA2485A1503127F90C7FCA215074815F05AA2150F16E05AED1FC0A2
+1680153F16005D157E5D007C495A007E495A003E5C4A5A6CEB1F80260F803EC7FC3807C0
+FC3801FFF038003F80252D75AB32>I<D903E0137E903A07F801FF80903A0E3C0783E090
+3A1C1E0F01F0903A3C1F1C00F801385B017849137C01705BA24A48137E01E05BA292C7FC
+00015B13C0147EC7FC02FE14FEA25CA20101140117FC5CA20103140317F85CA20107EC07
+F0A24AEB0FE0A2010F15C0EE1F80163F1700496C137E5E4B5A9138B803F090393F9C07E0
+91389E0F80DA07FEC7FCEC01F849C9FCA2137EA213FEA25BA21201A25BA21203A21207B5
+12F0A25C2F3F7FAB32>I<D801F0EB3F803A03FC01FFF03A071E03C0F83A0E0F0F007C00
+1E90389E01FC001C139CECB803003813F0A2D91FE013F80078EC00E00070491300A200F0
+5BEAE03F91C8FC1200A25B137EA313FE5BA312015BA312035BA312075BA3120F5BA3121F
+5B0007C9FC262D78AB29>114 D<EC0FE0EC7FF8903801F01E903803C00F903907800780
+90380F0003011E14C0150749131FA2017CEB3F801378137CED0E0092C7FC137E137F14F0
+14FF6D13C06D13F06D7F6D7F1300EC0FFE14011400157F81120E003F141E487EA2153E48
+C7123CA200FC5C12705D0078495A6C495A6CEB0F80260F803EC7FC3803FFF838007FC022
+2D7AAB28>I<1470EB01F8A313035CA313075CA3130F5CA3131F5CA2007FB512E0B6FC15
+C0D8003FC7FCA25B137EA313FE5BA312015BA312035BA312075BA3120F5BA2EC0780001F
+140013805C140E003F131EEB001C143C14385C6C13F0495A6C485AEB8780D807FEC7FCEA
+01F81B3F78BD20>I<137C48B414072603C780EB1F80380703C0000F7F000E153F121C01
+07150012385E1278D8700F147E5C011F14FE00F05B00E05DEA003FEC0001A2495C137E15
+0313FE495CA215071201495CA2030F13380003167849ECC070A3031F13F0EE80E0153F00
+011581037F13C06DEBEF8300000101148090397C03C787903A3E0F07C70090391FFE01FE
+903903F000782D2D78AB34>I<017CEE038048B4020EEB0FC02603C780013FEB1FE03807
+03C0000E7F5E001C037E130F01071607123804FE130300785DEA700F4A1501011F130100
+F001804914C012E0EA003FDA000314034C14805B137E0307140701FE1700495CA2030F5C
+0001170E495CA260A24848495A60A2601201033F5C7F4B6C485A000002F713036D9039E7
+E0078090267E01C349C7FC903A1F0781F81E903A0FFF007FF8D901FCEB0FE03B2D78AB41
+>119 D<02F8133FD907FEEBFFE0903A0F0F83C0F0903A1C07C780F890393803CF030170
+13EE01E0EBFC07120101C013F8000316F00180EC01C000074AC7FC13001407485C120EC7
+FC140F5DA3141F5DA3143F92C8FCA34AEB03C01780147EA202FEEB0700121E003F5D267F
+81FC130E6E5BD8FF83143CD903BE5B26FE079E5B3A7C0F1F01E03A3C1E0F83C0271FF803
+FFC7FC3907E000FC2D2D7CAB2D>I<137C48B414072603C780EB1F80380703C0000F7F00
+0E153F001C1600130712385E0078157EEA700F5C011F14FE00F0495B12E0EA003FEC0001
+5E5B137E150301FE5C5BA2150700015D5BA2150F00035D5BA2151F5EA2153F12014BC7FC
+6D5B00005BEB7C0390383E0F7EEB1FFEEB03F090C712FE5DA214015D121F397F8003F0A2
+4A5A4848485A5D48131F00F049C8FC0070137E007813F8383801F0381E07C06CB4C9FCEA
+01FC294078AB2F>I E
+%EndDVIPSBitmapFont
+%DVIPSBitmapFont: Fe cmsy10 12 1
+/Fe 1 16 df<49B4FC010F13E0013F13F8497F48B6FC4815804815C04815E04815F0A248
+15F8A24815FCA3B712FEA96C15FCA36C15F8A26C15F0A26C15E06C15C06C15806C15006C
+6C13FC6D5B010F13E0010190C7FC27277BAB32>15 D E
+%EndDVIPSBitmapFont
+%DVIPSBitmapFont: Ff cmr12 12 67
+/Ff 67 123 df<9239FFC001FC020F9038F80FFF913B3F803E3F03C0913BFC00077E07E0
+D903F890390FFC0FF0494890383FF81F4948EB7FF0495A494814E049C7FCF00FE0499139
+3FC0038049021F90C7FCAFB912F0A3C648C7D81FC0C7FCB3B2486CEC3FF0007FD9FC0FB5
+12E0A33C467EC539>11 D<4AB4FC020F13E091387F80F8903901FC001C49487FD907E013
+0F4948137F011FECFF80495A49C7FCA25B49EC7F00163E93C7FCACEE3F80B8FCA3C648C7
+FC167F163FB3B0486CEC7FC0007FD9FC1FB5FCA330467EC536>I<913801FFC0020FEBFB
+8091387F803F903801FC00494813FFEB07E0EB1FC0A2495A49C7FC167F49143F5BAFB8FC
+A3C648C7123FB3B2486CEC7FC0007FD9FC1FB5FCA330467EC536>I<001EEB03C0397F80
+0FF000FF131F01C013F8A201E013FCA3007F130F391E6003CC0000EB000CA401E0131C49
+1318A3000114384913300003147090C712604814E0000614C0000E130148EB038048EB07
+0048130E0060130C1E1D7DC431>34 D<121EEA7F8012FF13C0A213E0A3127FEA1E601200
+A413E013C0A312011380120313005A1206120E5A5A5A12600B1D78C41B>39
+D<140C141C1438147014E0EB01C01303EB0780EB0F00A2131E5BA25B13F85B12015B1203
+A2485AA3485AA348C7FCA35AA2123EA2127EA4127CA312FCB3A2127CA3127EA4123EA212
+3FA27EA36C7EA36C7EA36C7EA212017F12007F13787FA27F7FA2EB0780EB03C01301EB00
+E014701438141C140C166476CA26>I<12C07E12707E7E7E120F6C7E6C7EA26C7E6C7EA2
+1378137C133C133E131E131FA2EB0F80A3EB07C0A3EB03E0A314F0A21301A214F8A41300
+A314FCB3A214F8A31301A414F0A21303A214E0A3EB07C0A3EB0F80A3EB1F00A2131E133E
+133C137C13785BA2485A485AA2485A48C7FC120E5A5A5A5A5A16647BCA26>I<14F0A280
+5CA70078EC01E000FCEC03F0B4140FD87F80EB1FE0D83FC0EB3FC03A0FF060FF003903F8
+61FC3900FC63F090383F6FC0D90FFFC7FCEB03FCEB00F0EB03FCEB0FFF90383F6FC09038
+FC63F03903F861FC390FF060FF3A3FC0F03FC0D87F80EB1FE0D8FF00EB0FF000FC140300
+78EC01E0C790C7FCA7805CA2242B7ACA31>I<16C04B7EB3AB007FBAFCBB1280A26C1900
+C8D801E0C9FCB3AB6F5A41407BB84C>I<121EEA7F8012FF13C0A213E0A3127FEA1E6012
+00A413E013C0A312011380120313005A1206120E5A5A5A12600B1D78891B>I<B612C0A6
+1A067F9721>I<121EEA7F80A2EAFFC0A4EA7F80A2EA1E000A0A78891B>I<1618163C167C
+A2167816F8A216F01501A216E01503A216C01507A21680150FA2ED1F00A2151E153EA215
+3C157CA2157815F8A25D1401A24A5AA25D1407A25D140FA292C7FC5CA2141E143EA2143C
+147CA25CA25C1301A25C1303A25C1307A25C130FA291C8FC5BA2133EA2133C137CA21378
+13F8A25B1201A25B1203A2485AA25B120FA290C9FC5AA2121E123EA2123C127CA2127812
+F8A25A126026647BCA31>I<143014F013011303131F13FFB5FC13E713071200B3B3B049
+7E497E007FB6FCA3204278C131>49 D<EB03FE90381FFFC0017F13F03901F80FFC3903C0
+01FE48486C7E000EC7EA7F8048EC3FC0ED1FE04815F00030140F007015F800601407126C
+B415FC7F7F1503A46C4813076CC7FCC8FC16F8A2150F16F0151F16E0A2ED3FC0ED7F8016
+005D5D4A5A4A5A4A5A5D4A5A4A5A4AC7FC147C5C5C495A495A495A49C7120C131E5B0138
+14185B5B485A4848143848C81230000E1570001FB612F0A25A5AB712E0A326427BC131>
+I<49B4FC010F13E0013F13FC9038FE01FE3A01F0007F80D803C0EB3FC048C7EA1FE0120E
+ED0FF0EA0FE0486C14F8A215077F5BA26C48130FEA03C0C813F0A3ED1FE0A2ED3FC01680
+ED7F0015FE4A5AEC03F0EC1FC0D90FFFC7FC15F090380001FCEC007FED3F80ED1FC0ED0F
+E016F0ED07F816FC150316FEA2150116FFA3121EEA7F80487EA416FE491303A2007EC713
+FC00701407003015F80038140F6C15F06CEC1FE06C6CEB3FC0D803E0EB7F803A01FE01FE
+0039007FFFF8010F13E0010190C7FC28447CC131>I<ED0380A21507150FA2151F153FA2
+157F15FFA25CEC03BF153F14071406140C141C141814301470146014C013011480EB0300
+5B13065B131C13185B1370136013E0485A5B120390C7FC1206120E120C5A123812305A12
+E0B812C0A3C8383F8000ADEDFFE0027FEBFFC0A32A437DC231>I<000615C0D807C01307
+01FCEB7F8090B612005D5D5D15E0158026063FFCC7FC90C9FCAE14FF010713C090381F01
+F090383800FC01F0137ED807C07F49EB1F8016C090C7120F000615E0C8EA07F0A316F815
+03A216FCA5123E127F487EA416F890C712075A006015F0A20070140F003015E00038EC1F
+C07E001EEC3F806CEC7F006C6C13FE6C6C485A3901F807F039007FFFE0011F90C7FCEB07
+F826447BC131>I<EC07FCEC3FFF91B512C0903903FC03E0903907E000F0D91FC0133849
+C71258017EEB01FC01FE1303491307485A485AA24848EB03F8000FEC01F092C7FC485AA3
+485AA3127FA29038007F80903801FFF090380780FC39FF0E003E49EB1F8049EB0FC049EB
+07E0136001E0EB03F04914F8150116FC5BED00FEA390C812FFA47EA57F123FA216FE121F
+15016D14FC120FED03F86C7EED07F06C6C14E06C6CEB0FC06C6CEB1F80017EEB3F009038
+3F80FE90380FFFF8010313E00100138028447CC131>I<121EEA7F80A2EAFFC0A4EA7F80
+A2EA1E00C7FCB3A5121EEA7F80A2EAFFC0A4EA7F80A2EA1E000A2B78AA1B>58
+D<007FBAFCBB1280A26C1900CEFCB0007FBAFCBB1280A26C190041187BA44C>61
+D<16C04B7EA34B7EA34B7EA34B7EA3ED19FEA3ED30FFA203707FED607FA203E07FEDC03F
+A2020180ED801FA2DA03007F160FA20206801607A24A6D7EA34A6D7EA34A6D7EA2027081
+0260147FA202E08191B7FCA249820280C7121FA249C87F170FA20106821707A2496F7EA3
+496F7EA3496F7EA201788313F8486C83D80FFF03037FB500E0027FEBFFC0A342477DC649
+>65 D<B8FC17E017FC00019039C00003FF6C6C4801007FEF3FC0717E717E717E84170384
+170184A760A21703601707604D5A4D5AEF7FC04DC7FCEE03FEEE3FF091B65A17FC0280C7
+B47EEF1FC0EF0FF0717E717E717E717E1980187F19C0A2183F19E0A8F07FC0A2198018FF
+4D1300A24D5AEF0FFC4D5AEF7FE048486C903803FFC0B9C7FC17FC17C03B447CC345>I<
+DB0FFE146092B500C013E0020314F0913A0FFC01FC0191393FC0003E02FFC7EA0F83D903
+FCEC03C74948EC01E74948EC00FF4948157F4948153F4948151F49C9120F485A49160712
+0348481603A248481601A248481600A2123FA2491760127FA31900485AAE6C7EA21960A2
+123F7FA2001F18E07F000F18C0A26C6C160119806C6C160312016DEE07006C6C16066D6C
+150E6D6C5D6D6C5D6D6C15786D6C5D6D6C4A5AD900FFEC0780DA3FC0011FC7FCDA0FFC13
+FC0203B512F0020014C0DB0FFEC8FC3B487BC546>I<B8FC17F017FC00019039C00007FF
+6C499038007FC0017FED1FE0EF07F0EF03FC717E717E84727E727E727EA2727E85180385
+A2180185A38584A31A80AD1A00A36061A361180361180761180F614E5A183F614EC7FC18
+FEEF03FC4D5AEF1FE001FFED7FC0486DD907FFC8FCB812FC17F094C9FC41447CC34B>I<
+B912F8A3000101C0C7127F6C6C48EC07FC17011700187C183C181CA284A31806A4180704
+067FA395C7FCA4160EA2161E163E16FE91B5FCA3EC8000163E161E160EA21606A319C0A3
+F0018093C7FCA41803A21900A260A260A2181EA2183E187EEF01FE170748486C147FB95A
+A33A447CC342>I<B912F0A3000101C0C7127F6C6C48EC0FF817031701170018781838A2
+181CA3180CA4180E1806160CA21800A5161CA2163C167CED01FC91B5FCA3EC8001ED007C
+163C161CA2160CA793C8FCB08048487EB612F8A337447CC340>I<DB0FFE146092B500C0
+13E0020314F0913A0FFC01FC0191393FC0003E02FFC7EA0F83D903FCEC03C74948EC01E7
+4948EC00FF4948157F4948153F4948151F49C9120F485A491607120348481603A2484816
+01A248481600A2123FA2491760127FA396C7FC485AAD4CB612C06C7EA293C7387FF00072
+5A003F171F7FA2121F7F120FA26C7EA26C7E6C7EA26C7E6D7E6D6C153F6D7E6D6C157F6D
+6C15E7D903FEEC01C7D900FFEC0383DA3FE0EB0F01DA0FFCEBFE000203B500F813600200
+02E090C7FCDB0FFEC9FC42487BC54D>I<B6D8C003B6FCA3000101E0C70007138026007F
+80913801FE00B3A991B7FCA30280C71201B3AC2601FFE0913807FF80B6D8C003B6FCA340
+447CC349>I<B612F0A3C6EBF0006D5A6D5AB3B3B3A4497E497EB612F0A31C447DC323>I<
+B612F8A3000101E0C9FC6C6C5A5CB3B31830A418701860A518E0A3EF01C0A217031707A2
+170F173F177FEE01FF48486C011F1380B9FCA334447CC33D>76 D<B56C933807FFFC6E5E
+A20001F1FE0026006FE0EE1BF8A3D967F01633A2D963F81663A3D961FC16C3A3D960FEED
+0183A2027FED0303A36E6C1406A36E6C140CA26E6C1418A36E6C1430A36E6C1460A26E6C
+14C0A36E6CEB0180A3037FEB0300A292383F8006A36F6C5AA36F6C5AA26F6C5AA36F6C5A
+A36F6C5AA26FB45AA370C7FC13F0A2486C143ED80FFFEF0FFEB500F0011C0107B512FCA3
+4E447BC359>I<B56C020FB5FC8080C6040013F06D6CED1F80D96FF8ED0F00A2D967FC15
+06EB63FEA2EB61FF01607FA26E7E6E7EA26E7E6E7EA26E7E6E7EA26E7E6E7FA26F7E6F7E
+A26F7E6F7EA26F7E6F7EA26F7E6F1380A2EE7FC0EE3FE0A2EE1FF0EE0FF8A2EE07FCEE03
+FEA2EE01FF701386A2EF7FC6EF3FE6A2EF1FF6EF0FFEA217071703A217011700A201F016
+7E183E487ED80FFF161EB500F0150EA2180640447CC349>I<ED1FFC4AB512C0913907F0
+07F091391F8000FC027EC7123FD901F8EC0FC049486E7E49486E7E49486E7E49486E7E49
+C9127E017E8201FE834848707E4848707EA24848707EA2000F84491603001F84A2484870
+7EA3007F84A24982A300FF1980AD6C6C4C1300A4003F606D1603A2001F60A26C6C4C5AA2
+6C6C4C5AA20003606D161F6C6C4C5A000060017F4CC7FC6E5D013F5E6D6C4A5AD907E0EC
+03F06D6C4A5AD901FCEC1FC0D9007E4AC8FCDA1F8013FC913907F007F00201B512C09126
+001FFCC9FC41487BC54C>I<B712FCEEFFC017F800019039C0000FFC6C6C48EB01FF9338
+007F80EF1FE0170FEF07F018F8EF03FCA218FE1701A218FFA718FEA2170318FCA2EF07F8
+18F0EF0FE0EF1FC0EF7F80933801FE00EE0FFC91B612F017800280C9FCB3AA3801FFE0B6
+12C0A338447CC342>I<ED1FFC4AB512C0913907F007F091391F8000FC027EC7123F4948
+EC1FC0D903F0EC07E049486E7E49486E7E49486E7E49C9127E49167F01FE707E4848707E
+00038449160F000784491607000F84A24848707EA2003F84491601A2007F84A34982A200
+FF1980AD007F19006D5EA3003F60A26D1603001F60A2000F606D16070007606DD903F013
+0F0003DA0FFC5C6DD91C0E131F00014A6C5C6C6C903A3003803F80017FD9700149C7FC92
+386000C0D93F8015FED91FC0ECE1FCD907E0EC63F0D903F0EC77E0902601FC70EB7FC090
+26007E3091C8FCDA1FB813FC912707FC07F814C00201B57E9139001FFC3C92C7FC053E13
+01171E051F13031A80F08007F0C00F94380FF03F95B51200A28361715BA2715B9438007F
+E0F01F8042597BC54C>I<B712E016FF17C000019039C0003FF86C6C48EB03FCEE00FF71
+7E717E717E717E717EA284170384A760A21707604D5AA24D5A4D5A4DC8FCEE01FEEE07F8
+EE3FE091B6C9FC16FC913980007F80EE0FE0707EEE03FC707E160083717EA2717EA784A7
+1A6084171FA21AE0716C13C02601FFE002071301B600C01680943801FC03943900FE0700
+CBEA3FFEF007F843467CC348>I<49B41303010FEBE007013F13F89039FE00FE0FD801F8
+131FD807E0EB079F49EB03DF48486DB4FC48C8FC4881003E81127E82127C00FC81A282A3
+7E82A27EA26C6C91C7FC7F7FEA3FF813FE381FFFE06C13FE6CEBFFE06C14FC6C14FF6C15
+C0013F14F0010F80010180D9001F7F14019138001FFF03031380816F13C0167F163F161F
+17E000C0150FA31607A37EA36C16C0160F7E17806C151F6C16006C5D6D147ED8FBC05CD8
+F9F0495AD8F07C495A90393FC00FE0D8E00FB51280010149C7FC39C0003FF02B487BC536
+>I<003FB912F8A3903BF0001FF8001F01806D481303003EC7150048187C0078183CA200
+70181CA30060180CA5481806A5C81600B3B3A54B7EED7FFE49B77EA33F447DC346>I<B6
+00C0010FB5FCA3000101E0C813F026007F80ED1F80F00F00A21806B3B3A7180E6D6C150C
+A2181C131F6E1518010F163818306D6C1570606D6C14016D6C5D6D6CEC0780027F4AC7FC
+6E6C131EDA1FE0137C913907FC03F00201B55A6E6C1380DB07FCC8FC40467CC349>I<B6
+92383FFFF0A3000301E003071300C649ED01FC4A5E017F705A6E5E133F616E1501011F5F
+A26D6C4BC7FCA28001071606A26E150E0103160CA26D6C5DA2806D5EA26F1470027F1560
+81023F5DA281021F4A5AA26F1303020F92C8FC8102071406A26F130E0203140CA26E6C5B
+A2816E5CA2EE8070037F1360A26F6C5AA216E092381FE180A216F3030F90C9FC16FBED07
+FEA36F5AA36F5AA26F5AA3166044467EC349>I<EB07FC90383FFF809038F80FE03903C0
+03F048C66C7E000E6D7ED80FC0137E486C137F6D6D7EA36F7EA26C5AEA0380C8FCA4EC0F
+FF49B5FC90380FFE1FEB3FC0EBFF00EA03FC485A485A485A485A127F5B176048C7FCA315
+3FA36D137F007F14EF6D9038C7E0C0003F13013A1FE00783F13B07F81E03FF802701FFFC
+0113003A001FE0007C2B2E7CAC31>97 D<EA01FC12FFA3120712031201B3EC03FC91380F
+FF8091383C07E091387001F89039FDE0007E02807F01FFEC1F8091C713C049EC0FE04914
+0717F0A2EE03F8A217FCA2160117FEAB17FC1603A217F8A2EE07F0A26DEC0FE017C06D14
+1F01FBEC3F80D9F380EB7E00D9E1C05B9039E0F001F89039C03C07E09039801FFF80C7D8
+03FCC7FC2F467DC436>I<EC7F80903803FFF090380FC07C90383F000F01FCEB03804848
+EB01C00003140F4848EB1FE049133F120F485AA2485AED1FC0007FEC070092C7FCA290C9
+FC5AAB7E7FA2123F16307F001F15706C6C146016E06C6C14C06C6C13010001EC03806C6C
+EB0700013F131E90381FC078903807FFF001001380242E7DAC2B>I<167FED3FFFA31501
+8182B3EC7F80903803FFF090380FC07C90383F000E017E1307496D5AD803F87F48487F5B
+000F81485AA2485AA2127FA290C8FC5AAB7E7FA2123FA26C7EA2000F5D7F6C6C5B00035C
+6C6C9038077F806C6C010E13C0013F011C13FE90380FC0F8903803FFE09026007F001300
+2F467DC436>I<EB01FE903807FFC090381F03F090387E00FC49137E48487F485A4848EB
+1F80000F15C049130F121F484814E01507A2007F15F090C7FCA25AA390B6FCA290C9FCA6
+7EA27FA2123F16306C7E1670000F15606D14E06C6C14C0000314016C6CEB03806C6CEB07
+00013E131E90381F80F8903803FFE0010090C7FC242E7DAC2B>I<EC0FE0EC7FF8903801
+F81E903803F03F90390FE07F8090381FC0FF5C133F495AA2ED7F0001FE131C92C7FCAFB6
+7EA3C648C8FCB3B2486C7E007F13FFA321467EC51E>I<EE0F80D901FCEB7FE0903A0FFF
+81F0F090393F07E3819039FC01FF033A01F800FE014848017E13E00007027FC7FC497F00
+0F8149131F001F81A9000F5D6D133F000792C7FC6D5B0003147E6C6C5B6D485A3903BF07
+E090380FFF80260701FCC8FC90CAFCA25AA37F6C7E7F90B512F86C14FF16E06C15F86C6C
+8048B67E3A07C0000FFF48481300003FC8EA3F80003E151F48ED0FC0A2481507A56C150F
+007C1680007E151F003E16006C153E6C6C5CD807E0495AD801F8EB07E0D8007FEB3F8090
+261FFFFEC7FC010113E02C427DAC31>I<EA01FC12FFA3120712031201B3EC01FE913807
+FFC091381E07F091383801F802707FECE000D9FDC07F5C01FF147F91C7FCA25BA35BB3A8
+486CECFF80B5D8F83F13FEA32F457DC436>I<EA01E0EA07F8A2487EA46C5AA2EA01E0C8
+FCADEA01FC12FFA3120712031201B3B0487EB512F8A315437DC21C>I<143C14FFA24913
+80A46D1300A2143C91C7FCADEC7F80EB3FFFA31300147F143FB3B3AA123E127F39FF807F
+00A2147EA25C6C485A383C01F06C485A3807FF80D801FEC7FC195785C21E>I<EA01FC12
+FFA3120712031201B3A292381FFFE0A36F1300ED07F816E05E5E030EC7FC5D5D5D5D4A5A
+4A5A4AC8FC5CEC3F804A7E14FF9038FDCFE09038FF8FF01407496C7E01FC7F14016E7E81
+816F7E82151F6F7E821507826F7E8282486C491380B5D8F81F13F8A32D457DC433>I<EA
+01FC12FFA3120712031201B3B3B3A5487EB512F8A315457DC41C>I<D801FC01FFEC1FE0
+00FF010701E0EBFFFC913B0F03F801E07F913C3C01FC07803F800007903C7000FE0E001F
+C0000349D97E1C130F2601FDC0D97F38804A143001FFDA3FF06D7E91C75BA2495DA3495D
+B3A8486C4A6C497EB5D8F81FB50003B512E0A34B2C7DAB52>I<3901FC01FE00FF903807
+FFC091381E07F091383801F8000701707F0003EBE0002601FDC07F5C01FF147F91C7FCA2
+5BA35BB3A8486CECFF80B5D8F83F13FEA32F2C7DAB36>I<EC7F80903803FFF090380FC0
+FC90383E001F496D7E496D7E48486D7E48486D7E48486D7E000F81A24848147E003F157F
+A290C87E481680A44816C0AA6C1680A26D147F003F1600A2001F157E6D14FE000F5D6D13
+0100075D6C6C495A6C6C495A6C6C495A013E49C7FC90381FC0FE903807FFF89038007F80
+2A2E7DAC31>I<3901FC03FC00FF90380FFF8091383C07E091387001F83A07FDE000FE00
+030180137FD801FFEC3F8091C7EA1FC04915E049140F17F0160717F8160317FCA3EE01FE
+ABEE03FCA3EE07F8A217F0160F6D15E0EE1FC06D143F17806EEB7E00D9FDC05B9039FCF0
+03F891383C0FE091381FFF80DA03FCC7FC91C9FCAE487EB512F8A32F3F7DAB36>I<9138
+7F8003903903FFE00790380FE07890393F801C0F90387E000E496D5AD803F8EB039F0007
+EC01BF4914FF48487F121F5B003F81A2485AA348C8FCAB6C7EA3123F7F121F6D5C120F6D
+5B12076C6C5B6C6C497E6C6C130E013F131C90380FC0F8903803FFE09038007F0091C7FC
+AEEEFF80033F13FEA32F3F7DAB33>I<3903F803F000FFEB1FFCEC3C3EEC707F0007EBE0
+FF3803F9C000015B13FBEC007E153C01FF13005BA45BB3A748B4FCB512FEA3202C7DAB26
+>I<90383FE0183901FFFC383907E01F78390F0003F8001E1301481300007C1478127800
+F81438A21518A27EA27E6C6C13006C7E13FC383FFFE06C13FC6C13FF6C14C06C14E0C614
+F0011F13F81300EC0FFC140300C0EB01FE1400157E7E153EA27EA36C143C6C147C15786C
+14F86CEB01F039F38003E039F1F00F8039E07FFE0038C00FF01F2E7DAC26>I<1306A513
+0EA4131EA3133E137EA213FE12011207001FB512F0B6FCA2C648C7FCB3A4150CAA017E13
+1C017F1318A26D133890381F8030ECC070903807E0E0903801FFC09038007F001E3E7EBC
+26>I<D801FC147F00FFEC3FFFA300071401000380000181B3A85EA35DA212006D5B017E
+9038077F80017F010E13C06D011C13FE90380FC078903803FFF09026007F8013002F2D7D
+AB36>I<B539F001FFFCA3000790C7EA7FE06C48EC1F8000011600160E1200160C017F5C
+A280013F5CA26E1370011F146080010F5CA2ECF00101075CA26D6C48C7FCA26E5A010113
+06A26D6C5AA214FF6E5AA215B8EC3FB015F06E5AA36E5AA26E5AA36EC8FC2E2C7EAA33>
+I<B500E0B539E03FFF80A30007903C000FFE000FFC00D803FCD903F8EB03F8F001E01201
+03015D6D80000060A26D6E13036DD9037E91C7FCA20280017F5B013FD9063F1306A2D91F
+C06E5AED0C1FA2D90FE06E5AED180FA2D907F06E5AED3007A2D903F86E5AED6003A29026
+01FCE06D5AEDC00117FCD900FFECFD80ED800017FF027F92C8FC92C77EA26E147E023E14
+3EA2021E143C021C141CA2412C7EAA46>I<B539F007FFFCA30003D9C00113C0C6496C13
+00017F14FC013F5C6E13E06D7E010F495A6D6C485A02F890C7FC903803FC060101130E6E
+5A903800FF186E5AEC3FF05D141F140F6E7E81140FEC0DFCEC19FEEC38FF4A7E9138603F
+8002C07F0101131F49486C7E02007F01066D7E010E1303496D7E013C80017C80D801FC15
+80D80FFE4913C0B5D8800F13FFA3302B7FAA33>I<B539F001FFFCA3000790C7EA7FE06C
+48EC1F8000011600160E0000150C6D141C6D1418A26E1338013F1430A26D6C5BA26E13E0
+010F5CA26D6C485AA2ECF803010391C7FCA2903801FC06A2ECFE0E0100130CA2EC7F18A2
+15B8EC3FB0A2EC1FE0A36E5AA26E5AA36EC8FCA21406A35CA25CA2123C007E5BB4FC5CA2
+5CEAFE01387C0380D87007C9FCEA3C1EEA0FFCEA03F02E3F7EAA33>I<003FB612E0A290
+38C0003F90C713C0003CEC7F800038ECFF00A20030495A0070495AA24A5A0060495AA24A
+5A4A5AA2C7485A4AC7FC5B5C495A13075C495A131F4A1360495A495AA249C712C0485AA2
+485A485A1501485A48481303A24848EB07804848131F00FF14FF90B6FCA2232B7DAA2B>
+I E
+%EndDVIPSBitmapFont
+%DVIPSBitmapFont: Fg cmbx12 17.28 17
+/Fg 17 86 df<19F0F001F8F003FCA3180719F8180FA219F0181F19E0183FA219C0187F
+198018FFA219005F601703A260170760170FA260171F60173FA260177F6017FFA295C7FC
+5E5F1603A25F16075F160FA25F161F5F163FA25F167F5F16FFA294C8FC5D5E1503A25E15
+075E150FA25E151F5EA2153F5E157FA25E15FF93C9FC5CA25D14035D1407A25D140F5D14
+1FA25D143F5D147FA25D14FF92CAFC5BA25C13035C1307A25C130F5C131FA25C133F5C13
+7FA25C13FF91CBFC5AA25B12035B1207A25B120F5B121FA25B123F5B127FA25B12FF90CC
+FCA3127E123C3E9077EB51>47 D<ED0FFF4AB512F8020F14FF023F15C091B712F049D9FC
+037F0107D9F00013FE4901C0EB3FFF4990C7000F7F49486E7F017F8349486E7F4A804884
+48496E7FA248844A157F4884A3481980A34819C04A81A34819E0A7B518F0B3A86C19E0A7
+6C19C0A26E5DA26C1980A36C1900A36C6D4B5AA26C60A26C6D4A5B6C606E5C6D6C4A5B6D
+6C4A5B6D6D495B6D6D4990C7FC6D01F0EBFFFE6DD9FC035B010090B612F0023F15C0020F
+92C8FC020114F8DA001F138044607ADD51>I<16F04B7E1507151F153FEC01FF1407147F
+010FB5FCB7FCA41487EBF007C7FCB3B3B3B3007FB91280A6395E74DD51>I<913801FFF8
+021FEBFFC091B612F8010315FF010F16C0013F8290267FFC0114F89027FFE0003F7F4890
+C7000F7F48486E7FD807F86E148048486E14C048486E14E048486F13F001FC17F8486C81
+6D17FC6E80B56C16FE8380A219FFA283A36C5BA26C5B6C90C8FCD807FC5DEA01F0CA14FE
+A34D13FCA219F85F19F04D13E0A294B512C019804C14004C5B604C5B4C5B604C13804C90
+C7FC4C5A4C5A4B13F05F4B13804B90C8FC4B5AED1FF84B5A4B5A4B48143F4A5B4A48C8FC
+4A5A4A48157E4A5A4A5AEC7F8092C9FC02FE16FE495A495A4948ED01FCD90FC0150749B8
+FC5B5B90B9FC5A4818F85A5A5A5A5ABAFCA219F0A4405E78DD51>I<92383FFF800203B5
+12FC021FECFF80027F15E049B712F849D9F0077F010F90C76C7ED91FFCEC1FFFD93FF06E
+7F494802037F494882717F484980854890C9127FA24884183FA25A80A380806E157F6E5E
+14FE6E7E6F4A5A6C14F003FC495B03FF495B6C1580DCE0075B6CDBF80F90C7FC9338FE1F
+FE6C9238FF7FF84D5A6D16C06D5E6D4BC8FC6D6F7E6D16E00101826D16FC023F814A8149
+B87E010783498390263FFE3F8190267FFC0F819026FFF003814849C6FC48496D80484913
+1F4890C7000780160148486E1580003F163F49150F007F7014C0491501717E8400FF835B
+8484A384A21A80A27F007F1900607F003F606D160F001F606D4C5A6C6D153F6C6D4B5A6C
+01F04B5A6C01FC02035B6C01FF021F5B6D9027F001FFFEC7FC6D90B65A010F16F001035E
+010093C8FC020F14F8DA007F90C9FC426079DD51>56 D<ED3FFF0207B512F0023F14FC91
+B7FC010316C049D9F8077F49D9C00113F8013F496C6C7E4948C76C7E49486E7E48844849
+80717F4849825A48707F855A5C855A8583A2B583A41A80A71AC0A35F7EA46C5EA27E6E5C
+7EA26C5E6C7F6C5E6C6D147D6D6C14FD6D6CEB01F96D90388003F16D9038F01FE16D90B5
+00C11480010115816D6C1401021F13FC020113E091C8FC1A00A25FA261A3D9FF805E487F
+486D4A5B487FA2486D5E5F61615F614A4A90C7FC4D5A6C5B4A4A5A4A01035BD803FCC748
+5B6C6C021F13C0D9FFC0017F5B6CD9F803B5C8FC6DB612FC6D5D010F15E0010392C9FC01
+0014F8020F1380426079DD51>I<F00FE04E7EA24E7EA34E7EA24E7EA34D7FA24D80A24D
+80A34D80A24D80A34D80A2DD7FBF7FA2181F05FF8017FE04016D7FA24D7E04038217F804
+076D80A24D7E040F8217E0041F6D80A24D7F043F825F047F6E7FA294C77E4C825E03016F
+7FA24C800303845E03076F80A24C80030F845E031F6F80A24C81033F845E037F707F93B9
+FCA292BA7EA24A85A203FCC912070203865D020771805D86020F864B82021F865D87023F
+864B83027F8692CBFC874A864A840101875C496C728090381FFFC0B700E092B812FEA66F
+647BE37A>65 D<BB12E0F2FF801BF01BFE757E1CF0D800010280C7000780DF007F13FE08
+0F6D7E0801807480093F7F090F13FC757F757F877580767F8A88767F8A888AA2767FA28A
+881F80A37614C0A41FE0A5881FF0B05214E0A51FC0A4521480A31F006466A2525BA2525B
+A2525B666499B55A515C5191C7FC515B515B515B097F5B50B512C008075C083F91C8FC07
+07B512FCBD12F01CC051C9FC1BF81B8008E0CAFC6C627AE17C>68
+D<BD12FCA488A2D8000102C0C71201F1000F1A01F2007F1B3F1B0F1B07757EA28787A288
+A3F43F80A31C1FA3197EA3F40FC0A499C7FC19FEA31801A218031807181F18FF93B6FCA6
+EEC000181F180718031801A21800A21D7E197EA21DFCA696C812011DF8A31C03A3F407F0
+A31C0FA21C1F1C3F1DE01C7F1CFF63631B0F093F13C098B5FC1A0797B6FCBEFCA31D80A3
+5F617AE06A>I<B912E0A6C702E0C7FCB3B3B3B3AEB912E0A633627CE13C>73
+D<B912F8A6D8000102C0CBFCB3B3B1F307E0A5F30FC0A61B1FA31B3F1C80A21B7FA21BFF
+A262A262625013006262624FB5FC1907191F4EB6FCBDFC63A553627AE161>76
+D<B700C0083FB612F070627097B7FCA37061D800010DF8C7FC70F103EFA202FD6DF107CF
+A202FC6DF10F8FA36F6DF01F0FA26F6D183EA26F6D187CA26F6D18F8A36F6DEF01F0A26F
+6DEF03E0A26F6DEF07C0A26F6DEF0F80A3706DEE1F00A2706D163EA2706D5EA2706D5EA3
+706D4B5AA2706D4B5AA2706D4B5AA2706D4B5AA3716D4AC7FCA2716D143EA2716D5CA271
+6D5CA3716D495AA2716D495AA2716D495AA2716D495AA3726D48C8FCA272EBC03EA2726D
+5AA2726D5AA372EBF9F0A272EBFFE0A2725CA2725CA37390C9FCA2735AA2735A90381FFF
+C0B700F86E480207B812F0A3735AA2735A8C627AE199>I<B700E0040FB7128082828282
+A2D800016EDC000101FCC7FC719338001FC08383A28302FD808302FC80816F7F6F806F80
+84816F806F806F8084707F8270807080857080827080708085717F837180718071808683
+71807180727F8672808472807280877280847280737F87731480857314C07314E01CF073
+14F8857314FC7413FE7413FF1D9F867414DF7414FF86A286868787A287878787A2878788
+8888A288888890261FFFC084B712F8881D7F1D3F1D1F775A71627AE17E>I<94381FFFE0
+0407B67E043F15F04BB712FE030FEEFFC0033FD9FC0014F092B500C0010F13FC020349C7
+000113FF4A01F86E6C7F021F496F13E04A01C0030F7F4A496F7F91B5C96C7F0103497013
+FF494970804B834949717F49874949717F49874B8390B586484A717FA24891CB6C7FA248
+1D804A84481DC0A348497214E0A3481DF0A34A85481DF8A5B51CFCB06C1DF8A36E96B5FC
+A36C1DF0A46C6D4E14E0A36C1DC06E606C1D80A26C6E4D1400A26C6E4D5BA26C6E4D5BA2
+6D6D4D5B6D636D6D4D5B6F94B5FC6D636D6D4C5C6D6D4C91C7FC6D6E4B5B6D02E0031F5B
+023F6D4B13F06E01FC92B55A6E01FF02035C020302C0010F91C8FC020002FC90B512FC03
+3F90B712F0030F17C0030394C9FCDB007F15F804071580DC001F01E0CAFC666677E379>
+I<DBFFFCEC01E0020FD9FFE01303027F02FC130749B7130F0107EEC01F011F16F049D9C0
+07EBF83F4948C7383FFE7FD9FFF8020FB5FC4801E014014849804849153F91C97E484882
+001F834982003F83845B007F187FA2193FA200FF181FA27F190FA27FA26D17078080806C
+01F893C7FC80ECFF8015F86CECFFC016FC6CEDFFE017FE6CEEFFE018F86C17FE6C717E6C
+846C846D17F86D836D836D8313036D18806D6C17C0020F17E01401DA000F16F015000407
+15F8EE007F1703050014FC183F84060713FE84A2007C8300FC83A2197FA3193F7EA31AFC
+7EA27F1AF86D177F7F1AF06D17FF6D18E06D5E01FF18C06E4B138002E04B130002F84B5A
+02FFED3FFC01CF01E0ECFFF8018301FF010F5B010191B65A6D6C5E48011F93C7FC480103
+15FC48D9003F14E048020149C8FC476677E35A>83 D<001FBEFCA64849C79126E0000F14
+8002E0180091C8171F498601F81A0349864986A2491B7FA2491B3F007F1DC090C9181FA4
+007E1C0FA600FE1DE0481C07A5CA95C7FCB3B3B3A3021FBAFCA663617AE070>I<B96C02
+3FB612FEA6D8000102C0CA0007EBF000E2007FC7FCB3B3B3AA656D63A2821C0180657017
+0380525A6E7F6E4F5A70171F6E626E6D4D5A6E6D177F525A6E6E030390C8FC033F01E04B
+5A6F6DED1FFC6F01FCED7FF80303D9FF80903803FFE06F02F8017F5B6F6C90B7C9FC041F
+5E040716F8040016C0050F4ACAFCDD003F13C06F647AE17C>I E
+%EndDVIPSBitmapFont
+end
+%%EndProlog
+%%BeginSetup
+%%Feature: *Resolution 600dpi
+TeXDict begin
+%%PaperSize: A4
+
+%%EndSetup
+%%Page: 1 1
+1 0 bop 821 548 a Fg(A)-13 b(TM)53 b(SIMULA)-13 b(TION)54
+b(MODULE)1899 739 y Ff(b)m(y)1503 907 y(So)m(wm)m(y)m(a)33
+b(Manjanatha)941 1074 y(CNR)m(G,)g(Univ)m(ersit)m(y)g(of)f(New)i
+(Hampshire,)e(Durham)0 1407 y Fg(1)161 b(08/18/2000)0
+1626 y Ff(This)40 b(\014le)g(con)m(tains)h(the)f(information)d(ab)s
+(out)j(the)h(c)m(hanges)g(made)f(in)m(to)g(NS)g(2.1b6)g(to)g(enable)g
+(A)-8 b(TM)0 1747 y(sim)m(ulation.)38 b(The)27 b(A)-8
+b(TM)27 b(sim)m(ulator)c(w)m(as)k(added)f(on)g(to)g(NS)g(in)f(order)g
+(to)h(aid)f(our)g(researc)m(h)j(on)d(Mapping)0 1867 y(IP)33
+b(Di\013Serv)e(to)h(A)-8 b(TM)32 b(QoS.)g(Therefore,)i(only)d(those)i
+(features)g(of)e(A)-8 b(TM)33 b(that)f(w)m(ere)h(required)g(for)e(our)0
+1987 y(researc)m(h)j(w)m(as)g(added.)146 2228 y(These)h(w)m(ere)f(the)f
+(features)g(that)f(w)m(ere)i(necessary)h(for)d(our)h(researc)m(h:)119
+2456 y(1.)49 b(An)33 b(in)m(terface)f(to)h(add)f(and)h(delete)g(an)f(A)
+-8 b(TM)34 b(PV)m(C)f(on)g(a)f(No)s(de.)119 2660 y(2.)49
+b(A)33 b(PV)m(C)g(database)g(on)g(the)g(No)s(de)f(con\014gured)i(as)f
+(an)f(A)-8 b(TM)34 b(switc)m(h.)119 2863 y(3.)49 b(In)33
+b(order)f(to)h(con\014gure)g(a)f(No)s(de)h(as)g(a)f(switc)m(h,)360
+3092 y Fe(\017)48 b Ff(an)37 b(atmconditioner)d(w)m(as)k(added)f(on)g
+(to)f(the)h(no)s(de)g(\(basically)d(in)i(b)s(et)m(w)m(een)j(an)d
+(incoming)458 3212 y(link)c(and)h(the)g(no)s(de\).)360
+3374 y Fe(\017)48 b Ff(an)33 b(atmsc)m(heduler)g(w)m(as)g(added)h(on)e
+(to)g(the)h(outgoing)e(link)h(of)g(the)h(atm)e(switc)m(h.)119
+3602 y(4.)49 b(AAL5)34 b(capabilit)m(y)e(on)i(ev)m(ery)i(no)s(de)f
+(acting)e(as)h(an)g(edge.)49 b(\(this)34 b(is)g(not)g(required)h(on)f
+(the)g(switc)m(h)244 3723 y(since)f(segmen)m(tation)f(and)h(reassem)m
+(bly)g(do)s(es)g(not)f(happ)s(en)h(on)g(the)g(switc)m(h\).)146
+3951 y Fd(Ple)-5 b(ase)35 b(note)g(that)g(this)g(se)-5
+b(ction)34 b(only)h(explains)f(the)h(changes)f(made)g(to)h(the)g(C++)g
+(c)-5 b(o)g(de)34 b(under)h(the)0 4071 y(main)k(NS)h(dir)-5
+b(e)g(ctory.)60 b(A)n(l)5 b(l)40 b(the)g(OTcl)f(additions)g(wer)-5
+b(e)39 b(adde)-5 b(d)39 b(on)g(a)h(di\013er)-5 b(ent)39
+b(\014le)h(ns-atm.tcl)f(under)0 4192 y(tcl/lib)34 b(sub)-5
+b(dir)g(e)g(ctory.)45 b(Ple)-5 b(ase)34 b(se)-5 b(e)35
+b(ns-atm.tcl)f(for)h(al)5 b(l)34 b(the)h(OTcl)f(changes.)0
+4721 y Fc(1.1)135 b(Changes)46 b(made)f(to)h(the)f(existing)h(NS)f
+(Source:)0 4906 y Ff(The)33 b("atm")d(sub)s(directory)j(under)g(NS)f
+(con)m(tains)g(all)e(the)i(new)h(\014les)f(that)g(w)m(ere)h(added)g
+(for)e(adding)h(the)0 5026 y(A)-8 b(TM)33 b(sim)m(ulation)d(facilit)m
+(y)-8 b(.)0 5255 y Fb(classi\014er.cc/h:)48 b Ff(Classi\014er)23
+b(is)f(the)h(place)g(where)h(the)f(outgoing)f(pac)m(k)m(et)i(from)e(a)g
+(No)s(de)h(is)f(con)m(v)m(erted)j(to)244 5375 y(A)-8
+b(TM)30 b(PDU's.)43 b(The)30 b("recv")g(metho)s(d)f(forw)m(ards)h(pac)m
+(k)m(et)h(if)d(the)i(next)g(target)f(is)g(IP-based)h(or)f(cell)244
+5495 y(if)g(the)h(next)h(target)f(is)f(A)-8 b(TM)31 b(based.)44
+b(Therefore,)31 b(I)g(added)f(a)g(C++)g(metho)s(d)g("aal5)p
+3387 5495 30 4 v 33 w(pro)s(cessing")1926 5797 y(1)p
+eop
+%%Page: 2 2
+2 1 bop 244 548 a Ff(in)m(to)31 b(the)h(Classi\014er)f(so)h(that)f(a)g
+(pac)m(k)m(et)i(can)f(b)s(e)g(segmen)m(ted)g(b)s(efore)g(b)s(eing)f
+(sen)m(t)h(to)g(the)f(destina-)244 668 y(tion.)56 b(Note)37
+b(that,)h(if)e(the)h(No)s(de)g(on)g(to)g(whic)m(h)g(the)h(Classi\014er)
+f(is)f(attac)m(hed)i(is)f(the)g(destination)244 789 y(no)s(de)k(or)g(A)
+-8 b(TM)42 b(Switc)m(h)g(itself,)g(then)g(a)f("recv")h(metho)s(d)e
+(that)h(accepts)i(Cells)e(is)f(required)i(on)244 909
+y(the)36 b(Classi\014er.)52 b(If)36 b(the)g(No)s(de)f(turns)i(out)e(to)
+g(b)s(e)h(the)g(destination,)f(then)h(Cells)f(are)h(sen)m(t)h(to)e(y)m
+(et)244 1029 y(another)e(A)-8 b(TM)33 b(metho)s(d)f(i.e)g(the)h("re)p
+1648 1029 30 4 v 35 w(assem)m(bly")g(function.)244 1312
+y(So,)f(Classi\014er)h(needs)h(three)f(di\013eren)m(t)g(functions:)334
+1660 y(1.)48 b(aal5)p 639 1660 V 34 w(segmen)m(tation)334
+1822 y(2.)g(aal5)p 639 1822 V 34 w(reassem)m(bly)334
+1984 y(3.)g(recv)34 b(metho)s(d)e(that)g(accepts)i(Cells.)0
+2213 y Fb(ob)6 b(ject.cc:)49 b Ff(The)32 b("recv")g(metho)s(d)f(that)g
+(accepts)h(Cells)f(w)m(as)h(added)g(on)m(to)f(NsOb)5
+b(ject.)44 b(The)33 b("handle")244 2333 y(metho)s(d)f(w)m(as)h(c)m
+(hanged)h(to)e(handle)h(cells)e(as)i(w)m(ell.)0 2536
+y Fb(connector.cc/h:)49 b Ff(The)43 b("recv",)i("send")e(and)f("drop")g
+(metho)s(ds)g(that)g(accept)h(Cells)f(w)m(ere)h(added)244
+2657 y(on)m(to)32 b(Connector.)0 2860 y Fb(bi-connector.cc/h:)48
+b Ff(added)34 b("recv",sendUp,)h(sendDo)m(wn)f(metho)s(ds)e(with)g(a)h
+(Cell)e(*)h(parameter.)0 3064 y Fb(trace.cc:)48 b Ff(I)43
+b(added)g(a)f(new)h(i\))f(recv)h(and)g(ii\))d(format)h(function)h(to)g
+(trace)h(Cells.)72 b(This)43 b(co)s(de)f(needs)244 3184
+y(re-atten)m(tion.)73 b(I)43 b(w)m(ould)f(sa)m(y)i(it)d(should)i
+(basically)e(b)s(e)i(re-written.)73 b(First,)45 b(of)d(all,)h(I)g(just)
+g(put)244 3304 y(it)35 b(righ)m(t)g(no)m(w)h(so)g(that)g(when)h(I)f(ha)
+m(v)m(e)h(trace-all)d(enabled,)j(atleast)e(other)h(paths)h(except)g
+(for)f(the)244 3425 y(A)-8 b(TM)28 b(path)f(will)e(go)i(through.)42
+b(The)28 b(co)s(de)g(w)m(as)g(an)m(yw)m(a)m(ys)i(v)m(ery)f(messy)f(b)s
+(efore)g(b)s(ecause)g(the)g("for-)244 3545 y(mat")36
+b(function)h(is)f(to)s(o)h(long.)56 b(It's)38 b(hard)f(to)g(re-use)h
+(it.)57 b(Most)38 b(of)e(the)i(instructions)f(inside)g(can)244
+3665 y(b)s(e)32 b(functionized/metho)s(dized)e(so)i(that)f(new)h(trace)
+g(functions)g(can)g(b)s(e)f(easily)g(built)f(using)h(only)244
+3786 y(those)36 b(smaller)d(functions)j(for)f(e.g.)52
+b(\(let)35 b(us)h(sa)m(y)-8 b(,)37 b(w)m(e)g(ha)m(v)m(e)f(one)g(for)f
+(\015ags,)i(one)e(for)g(source/dest)244 3906 y(addresses)g(etc.\))44
+b(that)32 b(they)i(require.)244 4188 y(Re:)77 b(A)-8
+b(TM,)50 b(I)g(should)f(\014gure)h(out)f(the)h(trace)g(data)f(required)
+h(b)m(y)g(most)f(A)-8 b(TM)50 b(sim)m(ulations)244 4309
+y(and)c(then)h(dump)f(them.)83 b(Righ)m(t)45 b(no)m(w,)51
+b(the)46 b(only)g(sp)s(eci\014c)h(A)-8 b(TM)46 b(stu\013)h(are)f(VPI,)h
+(V)m(CI)g(and)244 4429 y(t)m(yp)s(e="atm".)c(Probably)-8
+b(,)32 b(the)h(ECN)g(bit)f(sen)m(t)i(during)e(congestion)g(b)m(y)h(A)-8
+b(TM)34 b(can)e(b)s(e)h(sp)s(eci\014ed)244 4550 y(in)e(place)h(of)g
+(the)g(existing)g(FLA)m(GS.)g(Also,)g(a)g(new)h(\015ag)f(for)f(BRM)i
+(and)f(FRM)g(cells)f(can)i(b)s(e)f(gen-)244 4670 y(erated.)244
+4952 y(Note)e(:)42 b(I)29 b(ha)m(v)m(e)i(also)e(incorp)s(orated)g(the)h
+(DequeT)-8 b(race)31 b(recv)g(metho)s(d.)42 b(This)29
+b(needs)j(mo)s(di\014cation)244 5073 y(as)h(w)m(ell.)0
+5276 y Fb(queue.cc:)50 b Ff(New)33 b(recv,)h(enque)g(and)f(deque)h
+(functions)e(for)g(the)h(main)e(queue.)0 5479 y Fb(red.cc:)49
+b Ff(New)33 b(enque)h(and)f(deque)h(functions)1926 5797
+y(2)p eop
+%%Page: 3 3
+3 2 bop 0 548 a Fb(droptail.cc:)47 b Ff(New)34 b(enque)g(and)f(deque)h
+(functions)0 740 y Fb(cellqueue.cc:)48 b Ff(This)35 b(is)f(a)g(new)i
+(queue)g(created)f(in)f(place)g(of)h(the)g(existing)f(P)m(ac)m(k)m
+(etQueue)j(class.)50 b(On)244 860 y(NS,)40 b(all)d(the)j(di\013eren)m
+(t)g(queueing)g(sc)m(hemes)h(suc)m(h)g(as)f(RED,)f(DropT)-8
+b(ail)37 b(use)k(the)f(P)m(ac)m(k)m(etQueue)244 980 y(metho)s(ds.)85
+b(Basically)-8 b(,)49 b(the)e(enquing)g(and)f(dequing)h(p)s(olicies)e
+(are)i(based)g(on)g(pac)m(k)m(ets)i(\(NOT)244 1101 y(b)m(ytes\))34
+b(in)e(these)i(queues.)0 1428 y Fg(2)161 b(08/29/2000)0
+1647 y Ff(As)43 b(of)f(to)s(da)m(y)-8 b(,)46 b(the)d(design)f(of)h(the)
+g(AAL5)f(implemen)m(tation)e(is)i(c)m(hanged)i(on)e(the)h(A)-8
+b(TM)44 b(sim)m(ulation)0 1767 y(mo)s(dule.)49 b(As)35
+b(indicated)f(in)g(the)h(ab)s(o)m(v)m(e)g(section,)h(creating)e(a)g
+(new)i(Cell)e(structure)i(impacted)e(a)g(lot)f(of)0 1887
+y(mo)s(dules)f(b)s(ecause)i(I)f(had)g(to)g(c)m(hange)h(the)f("recv",)h
+("send")f(and)g("drop")g(functions)g(in)f(all)f(the)i(classes)0
+2008 y(that)c(had)h(these)g(functions.)43 b(So,)30 b(I)g(c)m(hanged)g
+(the)g(desing)f(en)m(tirely)-8 b(.)42 b(A)30 b(Cell)e(is)h(basically)f
+(a)h(pac)m(k)m(et)i(with)0 2128 y(\014xed)j(size.)43
+b(I)33 b(created)h(a)e(structure)i(named)154 2430 y Fa(struct)53
+b(hdr_atm)g({)0 2671 y(.)0 2791 y(.)0 2912 y(.)0 3032
+y(.)0 3152 y(.)0 3393 y(};)146 3695 y Ff(A)m(t)27 b(the)g
+(classi\014er,)g(I)g(implemen)m(t)d(the)j("aal5)p 1783
+3695 30 4 v 33 w(pro)s(cessing")g(function)e(whic)m(h)i(basically)e
+(calls)g(the)i(seg-)0 3816 y(men)m(tation)g(and)h(reassem)m(bly)h
+(functions)f(of)f(the)i(class)f(AAL5.)42 b(In)28 b(the)h(AAL5)f(segmen)
+m(tation)f(function,)0 3936 y(I)e(generate)g(n)g(n)m(um)m(b)s(er)g(of)g
+(P)m(ac)m(k)m(ets)i(with)e(hdr)p 1685 3936 V 35 w(atm)f(allo)s(cated)f
+(in)h(them)g(\()h(basically)e(Cells\).)40 b(F)-8 b(or,)26
+b(ease)f(of)0 4056 y(information)k(analysis)i(in)h(ob)5
+b(jects)33 b(lik)m(e)f(connectors,)h(queues)i(etc.,)e(I)f(ha)m(v)m(e)h
+(also)f(allo)s(cated)e(a)i(hdr)p 3692 4056 V 35 w(cmn)0
+4177 y(in)g(all)e(the)j(P)m(ac)m(k)m(et)p 704 4177 V
+38 w(Cells)f(that)g(are)h(basically)d(mirroring)g(the)j(hdr)p
+2501 4177 V 35 w(cmn)g(of)f(the)h(original)c(pac)m(k)m(et.)0
+4460 y Fc(2.1)135 b(Changes)46 b(made)f(to)h(existing)g(NS)f(Source)0
+4644 y Ff(As)33 b(men)m(tioned)f(in)g(Marc)h(Greiss's)g(tutorial,)d(I)j
+(added)g(a)g(\014eld)f(in)m(to)308 4826 y Fa(struct)52
+b(p_info)h({)0 5067 y(.)0 5187 y(.)0 5308 y(.)410 5428
+y(name_[PT_ATM]="atm";)364 b(//ATM)53 b(extension,)h(CNRG,)e(UNH)308
+5548 y(};)1926 5797 y Ff(3)p eop
+%%Page: 4 4
+4 3 bop 146 548 a Ff(In)33 b Fd(enum)i(p)-5 b(acket)p
+803 548 30 4 v 35 w(t)p Ff(,)33 b(I)g(added)g(the)g(follo)m(wing)d
+(line)0 897 y Fa(enum)52 b(packet_t)i({)0 1137 y(.)0
+1258 y(.)0 1378 y(.)0 1499 y(PT_ATM)207 b(//ATM)52 b(extension,)i
+(CNRG,)f(UNH)0 1739 y(};)146 2088 y Ff(T)-8 b(o)46 b(the)f
+Fd(atm)h(sub)-5 b(dir)g(e)g(ctory)p Ff(,)49 b(I)c(added)h(t)m(w)m(o)g
+(new)g(\014les,)i Fd(atm.h/c)-5 b(c)45 b Ff(with)f(a)h
+Fd(struct)j(hdr)p 3485 2088 V 35 w(atm)d Ff(that)0 2208
+y(de\014nes)34 b(an)f(A)-8 b(TM)33 b(header.)1926 5797
+y(4)p eop
+%%Trailer
+end
+userdict /end-hook known{end-hook}if
+%%EOF
diff -urN ns-2.1b9/atm/README.tex ns-allinone-2.1b9/ns-2.1b9/atm/README.tex
--- ns-2.1b9/atm/README.tex	Wed Dec 31 19:00:00 1969
+++ ns-allinone-2.1b9/ns-2.1b9/atm/README.tex	Fri Jul 12 15:06:41 2002
@@ -0,0 +1,221 @@
+\documentclass[12pt]{article}
+\usepackage{psfig}
+\usepackage{graphics}
+%\setlength{\headheight}{0in}
+%\setlength{\headsep}{0in}
+\setlength{\textheight}{8.5in}
+%\setlength{\footskip}{0in}
+%\setlength{\footheight}{0.25in}
+\setlength{\oddsidemargin}{0pt}
+\setlength{\evensidemargin}{0pt}
+\setlength{\textwidth}{6.5in}
+\pagenumbering{arabic}
+%\renewcommand{\baselinestretch}{2.0}
+\pagestyle{plain}
+
+\begin{document}
+
+\begin{center}
+{\Large \bf ATM SIMULATION MODULE } \\[3mm]
+by\\[2mm]
+Sowmya Manjanatha\\[2mm]
+CNRG, University of New Hampshire, Durham\\[2mm]
+\end{center}
+
+\section{08/18/2000}
+
+     This file contains the information about the changes made into 
+NS 2.1b6 to enable ATM simulation.  The ATM simulator was added on to
+NS in order to aid our research on Mapping IP DiffServ to ATM QoS.  
+Therefore, only those features of ATM that were required for our research
+was added.   \\
+
+     These were the features that were necessary for our research:
+
+\begin{enumerate}
+\item An interface to add and delete an ATM PVC on a Node.
+\item A PVC database on the Node configured as an ATM switch.
+\item In order to configure a Node as a switch, 
+
+\begin{itemize} 
+        \item an atmconditioner was added on to the node (basically in
+              between an incoming link and the node).
+
+         \item an atmscheduler was added on to the outgoing link of
+	the atm switch.  \end{itemize}
+	
+\item AAL5 capability on every node acting as an edge. (this is not required on 
+   the switch since segmentation and reassembly does not happen on the switch).
+
+\end{enumerate}
+
+  {\it   Please note that this section only explains the changes made to the C++
+code under the main NS directory.  All the OTcl additions were added on a
+different file  ns-atm.tcl under tcl/lib subdirectory.  Please see ns-atm.tcl
+for all the OTcl changes. } \\ \\
+
+\subsection{Changes made to the existing NS Source:}
+
+     The "atm" subdirectory under NS contains all the new files that were added
+for adding the ATM simulation facility.
+
+\begin{description}
+\item [classifier.cc/h:] Classifier is the place where the outgoing packet from a Node
+                     is converted to ATM PDU's. The "recv" method forwards packet
+                     if the next target is IP-based or cell if the next target is
+                     ATM based.  Therefore, I added a C++ method "aal5\_processing"
+                     into the Classifier so that a packet can be segmented before
+                     being sent to the destination.  Note that, if the Node on
+                     to which the Classifier is attached is the destination node
+		     or ATM Switch itself, then a "recv" method that accepts Cells
+	             is required on the Classifier.  If the Node turns out to be
+		     the destination, then Cells are sent to yet another ATM method
+		     i.e the "re\_assembly" function.   \\
+
+	             So, Classifier needs three different functions: \\
+
+	            \begin{enumerate}
+
+		     \item aal5\_segmentation    
+		     \item aal5\_reassembly   
+                     \item recv method that accepts Cells.
+	            \end{enumerate}
+
+\item [object.cc:] The "recv" method that accepts Cells was added onto NsObject.
+                     The "handle" method was changed to handle cells as well.
+
+\item [connector.cc/h:] The "recv", "send" and "drop" methods that accept
+                      Cells were added onto Connector.
+
+\item [bi-connector.cc/h:] added "recv",sendUp, sendDown methods with a Cell * parameter.
+
+\item [trace.cc:]I added a new i) recv and ii) format function to trace Cells.
+                     This code needs re-attention.  I would say it should basically
+                     be re-written.  First, of all, I just put it right now so that
+                     when I have trace-all enabled, atleast other paths except for 
+                     the ATM path will go through.  The code was anyways very messy
+                     before because the "format" function is too long.  It's hard
+                     to re-use it.  Most of the instructions inside can be 
+                     functionized/methodized so that new trace functions can be 
+                     easily built using only those smaller functions for e.g.
+                     (let us say, we have one for flags, one for source/dest addresses etc.)
+                     that they require. \\
+
+                     Re: ATM, I should figure out the trace data required by most ATM 
+                     simulations and then dump them.  Right now, the only specific ATM
+                     stuff are VPI, VCI and type="atm". Probably, the ECN bit sent during
+                     congestion by ATM can be specified in place of the existing FLAGS.
+		     Also, a new flag for BRM and FRM cells can be generated. \\
+
+	             Note : I have also incorporated the DequeTrace recv method.  This
+                     needs modification as well. 
+
+\item [queue.cc:]  New recv, enque and deque functions for the main queue.
+
+\item [red.cc:]    New enque and deque functions
+
+\item [droptail.cc:] New enque and deque functions
+
+\item [cellqueue.cc:] This is a new queue created in place of the existing PacketQueue class.
+		     On NS, all the different queueing schemes such as RED, DropTail use
+	             the PacketQueue methods.  Basically, the enquing and dequing policies
+                     are based on packets (NOT bytes) in these queues.  
+
+
+\end{description}
+
+\section{08/29/2000}
+
+ 	As of today, the design of the AAL5 implementation is changed on the ATM simulation
+module.  As indicated in the above section, creating a new Cell structure impacted a lot of
+modules because I had to change the "recv", "send" and "drop" functions in all the classes
+that had these functions.  So, I changed the desing entirely.  A Cell is basically a packet
+with fixed size.  I created a structure named 
+
+\begin{verbatim}
+
+   struct hdr_atm {
+
+	.
+	.
+	.	
+	.
+	.
+
+	};
+
+\end{verbatim}
+
+	At the classifier, I implement the "aal5\_processing" function
+which basically calls the segmentation and reassembly functions of the
+class AAL5.  In the AAL5 segmentation function, I generate n number of
+Packets with hdr\_atm allocated in them ( basically Cells).  For, ease
+of information analysis in objects like connectors, queues etc., I
+have also allocated a hdr\_cmn in all the Packet\_Cells that are
+basically mirroring the hdr\_cmn of the original packet.  
+
+\subsection{Changes made to existing NS Source}
+
+	As mentioned in Marc Greiss's tutorial, I added a field into
+
+\begin{verbatim}
+      struct p_info {
+
+	.
+	.
+	.
+        name_[PT_ATM]="atm";       //ATM extension, CNRG, UNH
+      };
+\end{verbatim}
+
+	In {\em enum packet\_t}, I added the following line
+
+\begin{verbatim}
+
+	enum packet_t {
+
+	.
+	.
+	.
+	PT_ATM    //ATM extension, CNRG, UNH
+ 
+	};
+
+\end{verbatim}
+
+
+	To the {\em atm subdirectory}, I added two new files, {\em atm.h/cc}
+with a {\em struct hdr\_atm} that defines an ATM header.\\
+
+	
+\subsubsection{Changes to classifier.cc/h}
+
+\begin{enumerate}
+
+\item Added a new function {\em aal5_segmentation} for segmenting all
+Packets into ATM PDUs.  
+
+\item Added a new function {\em aal5_reassembly} for reassembling the
+incoming ATM PDUs into a frame/packet.
+
+\item Added a {\em bool atm} flag to indicate atm interface on a node.  
+
+\item Added probes in {\em recv} function to figure out
+any different i.e ATM treatment necessary. 
+\end{enumerate}
+
+\section{09/07/2000}
+
+\subsubsection{classifier.cc/h}
+Added a new function {\em switching} to switch pvcs if the node on
+which the classifier is installed is an atm switch.
+
+
+\end{document}
+
+
+
+
+
+
+
diff -urN ns-2.1b9/atm/README_user.tex ns-allinone-2.1b9/ns-2.1b9/atm/README_user.tex
--- ns-2.1b9/atm/README_user.tex	Wed Dec 31 19:00:00 1969
+++ ns-allinone-2.1b9/ns-2.1b9/atm/README_user.tex	Fri Jul 12 15:06:41 2002
@@ -0,0 +1,101 @@
+\documentclass[12pt]{article}
+\usepackage{psfig}
+\usepackage{graphics}
+%\setlength{\headheight}{0in}
+%\setlength{\headsep}{0in}
+\setlength{\textheight}{8.5in}
+%\setlength{\footskip}{0in}
+%\setlength{\footheight}{0.25in}
+\setlength{\oddsidemargin}{0pt}
+\setlength{\evensidemargin}{0pt}
+\setlength{\textwidth}{6.5in}
+\pagenumbering{arabic}
+%\renewcommand{\baselinestretch}{2.0}
+\pagestyle{plain}
+
+\begin{document}
+
+\begin{center}
+{\Large \bf ATM SIMULATION MODULE } \\[3mm]
+by\\[2mm]
+Sowmya Manjanatha\\[2mm]
+CNRG, University of New Hampshire, Durham\\[2mm]
+\end{center}
+
+\section{Configuration of an ATM Node }
+
+	I followed Sean Murphy's DSNode configuration because that
+seemed pretty simple.  ATM Node can configured in two ways :
+
+\begin{description}
+\item [Through the basic node on NS:]  
+
+	The following are the instructions to configure an ATM Node
+using the basic {\em node} structure in NS.  
+
+\begin{verbatim}
+
+          set atms [$ns node]
+
+	  #installing ATM condtioner
+          set conditioner [new AtmConditioner]
+          $ns atmconditioner $conditioner $source_node $atms
+
+          # adding the ATM scheduler to the outgoing link
+          $ns atm-duplex-link $atms $dest_node 1.5Mb 0.1ms
+
+\end{verbatim}
+
+	The ATM scheduler is attached to a simple link structure and this process
+is encapsulated in the {\em atm-duplex-link} and the  {\em atm-simplex-link} 
+procedures in ns-atm.tcl.
+
+\item [Using the ATMNode OTcl structure:]  All the functionalities described in the 
+instruction set of the previous case are encapsulated in the {\em ATMNode}
+OTcl class defined in ns-atm.tcl
+
+	You will just have to say:
+
+	set atms [new ATMNode]
+
+\end{description}
+
+\section{Configuring end stations}
+
+	The end-stations connected to either end of an ATM switch
+(ATMNode) must have an ATM interface and must be able to transmit and
+receive ATM PDU's instead of Packets.  The conversion from Packets to
+ATM PDU's are done by the ATM Adaptation Layer.  The ATM simulation
+module supports AAL5 layer only.  Additionally, the end-stations
+should possess the ability to establish and tear down Virtual Circuits
+(VCs).  ATM supports two different kinds of VCs, Switched Virtual
+Circuits (SVC) and Permanent Virtual Circuits (PVC).  SVCs are built and
+torn down via signaling while PVCs are configured manually.  In this
+implemenation, only PVCs are supported.  The AAL5 implementation on an
+end-station is enabled when a PVC is added to it.  This is done through
+the following instruction 
+
+\begin{verbatim}
+
+	set rxtp [new AtmTrafprm]
+
+	#setting required qos
+	$rxtp set-cbr 100 0.01
+
+	set txtp [new AtmTrafprm]
+	$txtp set-cbr 100 0.01
+
+     	$node add-pvc <vpi> <vci> <rxtp> <txtp>
+
+\end{verbatim}
+
+\end{document}
+
+
+
+
+
+
+
+
+
diff -urN ns-2.1b9/atm/README~ ns-allinone-2.1b9/ns-2.1b9/atm/README~
--- ns-2.1b9/atm/README~	Wed Dec 31 19:00:00 1969
+++ ns-allinone-2.1b9/ns-2.1b9/atm/README~	Fri Jul 12 15:06:41 2002
@@ -0,0 +1,109 @@
+
+--------------------------------------------------------------------------
+                            ATM SIMULATION MODULE
+                                    by
+                             Sowmya Manjanatha
+                    CNRG, University of New Hampshire, Durham
+--------------------------------------------------------------------------
+
+     This file contains the information about the changes made into 
+NS 2.1b6 to enable ATM simulation.  The ATM simulator was added on to
+NS in order to aid our research on Mapping IP DiffServ to ATM QoS.  
+Therefore, only those features of ATM that were required for our research
+was added.  
+
+     These were the features that were necessary for our research:
+
+1. An interface to add and delete an ATM PVC on a Node.
+
+2. A PVC database on the Node configured as an ATM switch.
+
+3. In order to configure a Node as a switch, 
+	
+	 - an atmconditioner was added on to the node (basically in between
+                                       an incoming link and the node).
+
+         - an atmscheduler was added on to the outgoing link of the atm switch.
+
+4. AAL5 capability on every node acting as an edge. (this is not required on 
+   the switch since segmentation and reassembly does not happen on the switch).
+
+
+     Please note that this section only explains the changes made to the C++
+code under the main NS directory.  All the OTcl additions were added on a
+different file  ns-atm.tcl under tcl/lib subdirectory.  Please see ns-atm.tcl
+for all the OTcl changes.
+
+     The "atm" subdirectory under NS contains all the new files that were added
+for adding the ATM simulation facility.
+
+CHANGES MADE TO THE EXISTING NS CODE:
+------------------------------------
+
+classifier.cc/h    : Classifier is the place where the outgoing packet from a Node
+                     is converted to ATM PDU's. The "recv" method forwards packet
+                     if the next target is IP-based or cell if the next target is
+                     ATM based.  Therefore, I added a C++ method "aal5_processing"
+                     into the Classifier so that a packet can be segmented before
+                     being sent to the destination.  Note that, if the Node on
+                     to which the Classifier is attached is the destination node
+		     or ATM Switch itself, then a "recv" method that accepts Cells
+	             is required on the Classifier.  If the Node turns out to be
+		     the destination, then Cells are sent to yet another ATM method
+		     i.e the "re_assembly" function.  
+
+	             So, Classifier needs three different functions:
+
+		     1) aal5_segmentation    
+		     2) aal5_reassembly   
+                     3) recv method that accepts Cells.
+               
+
+object.cc/h        : The "recv" method that accepts Cells was added onto NsObject.
+                     The "handle" method was changed to handle cells as well.
+
+connector.cc/h     : The "recv", "send" and "drop" methods that accept
+                      Cells were added onto Connector.
+
+bi-connector.cc/h  : added "recv",sendUp, sendDown methods with a Cell * parameter.
+
+trace.cc           : I added a new i) recv and ii) format function to trace Cells.
+                     This code needs re-attention.  I would say it should basically
+                     be re-written.  First, of all, I just put it right now so that
+                     when I have trace-all enabled, atleast other paths except for 
+                     the ATM path will go through.  The code was anyways very messy
+                     before because the "format" function is too long.  It's hard
+                     to re-use it.  Most of the instructions inside can be 
+                     functionized/methodized so that new trace functions can be 
+                     easily built using only those smaller functions for e.g.
+                     (let us say, we have one for flags, one for source/dest addresses etc.)
+                     that they require.
+
+                     Re: ATM, I should figure out the trace data required by most ATM 
+                     simulations and then dump them.  Right now, the only specific ATM
+                     stuff are VPI, VCI and type="atm". Probably, the ECN bit sent during
+                     congestion by ATM can be specified in place of the existing FLAGS.
+		     Also, a new flag for BRM and FRM cells can be generated.
+
+	             Note : I have also incorporated the DequeTrace recv method.  This
+                     needs modification as well.
+
+queue.cc           : New recv, enque and deque functions for the main queue.
+
+red.cc             : New enque and deque functions
+
+droptail.cc        : New enque and deque functions
+
+cellqueue.cc       : This is a new queue created in place of the existing PacketQueue class.
+		     On NS, all the different queueing schemes such as RED, DropTail use
+	             the PacketQueue methods.  Basically, the enquing and dequing policies
+                     are based on packets (NOT bytes) in these queues.  
+
+
+
+
+
+
+
+
+
diff -urN ns-2.1b9/atm/aal.cc ns-allinone-2.1b9/ns-2.1b9/atm/aal.cc
--- ns-2.1b9/atm/aal.cc	Wed Dec 31 19:00:00 1969
+++ ns-allinone-2.1b9/ns-2.1b9/atm/aal.cc	Fri Jul 12 16:22:13 2002
@@ -0,0 +1,294 @@
+/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
+/*
+ * Copyright (c) 2000 Regents of the University of New Hampshire.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the MASH Research
+ *      Group at the University of California Berkeley.
+ * 4. Neither the name of the University nor of the Research Group may be
+ *    used to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * 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.
+ *
+ * @(#) $Header: /opt/src/mash/repository/vint/ns-2/cell.h,v 1.0 2000/08/15 10:37 sow Exp $
+ *
+ * Contributed by Sowmya Manjanatha, Dept. of Computer Science, UNH, August 2000 
+ */
+
+#include "aal.h"
+#include "ip.h"
+#include <list>
+#include <stl.h>
+#include <vector>
+
+static class AAL5Class : public TclClass {
+public:
+	AAL5Class() : TclClass("AAL5") {}
+	TclObject* create(int, const char*const*) {
+		return (new AAL5());
+		
+	}	
+} class_aal5;
+
+
+
+Packet **AAL5::segment(Packet *p) {
+
+	int size = hdr_cmn::access(p)->size_ + 8;
+	
+	aal_uid = 0;
+	int x = size % 48;
+        size += (48 - x);
+
+	reassembly->tx_cell_cnt = size/48;
+	Packet *cell[2000];
+
+	for (int i = 0; i < reassembly->tx_cell_cnt; i++) {
+		cell[i] = Packet::alloc();
+                hdr_atm *atmh = hdr_atm::access(cell[i]);
+                atmh->packet = p;
+		initpkt(cell[i]);
+		atmh->vpi = reassembly->vpi;
+		atmh->vci = reassembly->vci;
+		
+		strcpy(atmh->switcher_,"");
+		cell[i]->set_atm();
+
+		if (i == (reassembly->tx_cell_cnt - 1)) {
+			atmh->type = LAST_CELL;
+		}
+		else 
+			atmh->type = 0;
+	}
+	     
+     return cell;
+
+}
+
+int AAL5::command(int argc, const char*const* argv) {
+
+       return (TclObject::command(argc,argv));
+
+}
+
+void AAL5::set_parameters(Reassembly *r, string type) {
+
+	reassembly = r;
+	aal_type_ = type;
+}
+
+void AAL5::initpkt(Packet *p) 
+{
+	// char buffer[20];
+
+	hdr_cmn* ch = hdr_cmn::access(p);
+	hdr_atm *atmh = hdr_atm::access(p);
+	hdr_ip *iph = hdr_ip::access(p);
+
+	hdr_ip *orig = hdr_ip::access(atmh->packet);
+
+
+	ch->uid() = aal_uid++;
+
+	ch->ptype() = PT_ATM;
+	ch->size() = CELLSIZE;
+
+	double local_time = Scheduler::instance().clock();
+
+	ch->timestamp() = (u_int32_t)(SAMPLERATE * local_time);
+	ch->iface() = UNKN_IFACE.value(); // from packet.h (agent is local)
+	ch->direction() = hdr_cmn::NONE;
+	ch->ref_count() = 0;	/* reference count */
+	ch->error() = 0;	/* pkt not corrupt to start with */
+
+	//required to find path of simulation
+	iph->ttl() = 1000000;
+	iph->saddr() = orig->saddr();
+	iph->sport() = orig->sport();
+	iph->daddr() = orig->daddr();
+	iph->dport() = orig->dport();
+
+	
+}
+
+void AAL5::increment() {
+
+	reassembly->tx_cell_cnt++;
+	
+}
+
+void AAL5::rx_increment() {
+
+	reassembly->rx_cell_cnt++;
+	
+}
+
+bool AAL5::cellcount_matches() {
+	
+	if(reassembly->tx_cell_cnt == reassembly->rx_cell_cnt) 
+		return true;
+	   
+	return false;
+}
+	   
+	
+Packet *AAL5::build_frm(Packet *orig) {
+
+
+	hdr_atm *temp = hdr_atm::access(orig);
+	//general elements of an ATM packet (Cell)
+	Packet *p = Packet::alloc();
+	hdr_atm *atmh = hdr_atm::access(p);
+	atmh->packet = orig;
+	initpkt(p);
+	atmh->vpi = reassembly->vpi;
+	atmh->vci = reassembly->vci;
+	atmh->type = 6;         //indicates RM cell
+	p->set_atm();
+	atmh->packet = temp->packet;
+
+	//parameters specific to FRM cell
+
+	string rm = string("00000001");   //protocol identifier for ABR
+
+	//Message type, length = 1 octet
+	(rm).append("0");   //DIR = 0 for frm
+	(rm).append("0");   //cell generated by a source
+	(rm).append("0");   //CI bit by source
+	(rm).append("0");   //NI initial
+	(rm).append("x");   //Req/ACK unused
+	(rm).append("xxx"); //reserved	
+
+
+	//ECR
+	char buf[16];
+	sprintf(buf,"%d", reassembly->txtp->pcr);
+	string s((16 - strlen(buf)),'0');
+	(rm).append(s);
+	(rm).append(buf);
+
+
+	//CCR
+	
+	sprintf(buf,"%d",reassembly->txtp->acr);
+	s = string((16 - strlen(buf)),'0');
+	(rm).append(s);
+	(rm).append(buf);
+
+
+	//MCR
+
+	sprintf(buf,"%d",reassembly->txtp->mcr);
+	s = string((16 - strlen(buf)),'0');
+	(rm).append(s);
+	(rm).append(buf);
+
+	// qlength - unused in ABR
+	s = string(32,'x');
+	(rm).append(s);
+
+	//seq # unused in ABR
+	(rm).append(s);
+
+	//Reserved bits
+	s = string(246,'x');
+	(rm).append(s);
+
+	//CRC
+	s = string(10,'1');
+	(rm).append(s);
+
+	// assign payload
+
+	//	printf("atmh->payload = 0x%x, length = %d\n",atmh->payload,(atmh->payload).length());
+
+	atmh->payload = new string(rm);
+	//atmh->payload.resize(atmh->payload.length() + rm.length());
+	//(atmh->payload).assign(rm);
+
+	return p;
+
+}
+
+void AAL5::adjust_source_rate (Packet *rm) {
+	
+	hdr_atm *atmh = hdr_atm::access(rm);
+	
+	string *s = atmh->payload;
+	AtmTrafprm *t = reassembly->txtp;
+	int ecr = atoi((atmh->payload->substr(16,16)).c_str());
+
+
+	if ((s->at(10) == '0') && (s->at(11) == '0')) {
+		double temp = min((double)t->pcr, t->acr + (t->rif * t->pcr));
+		double temp1 = min((double)ecr,temp);
+		t->acr = (int)(max((double)t->mcr, temp1));
+	}
+
+	else if ((s->at(10) == '1') && (s->at(11) == '0')) 
+		t->acr = max(t->mcr, (int)min((double)ecr,t->acr * (1 - t->rdf)));
+
+	else if ((s->at(10) == '0') && (s->at(11) == '1')) 
+		t->acr = max(t->mcr, min(ecr,t->acr));
+
+	else if ((s->at(10) == '1') && (s->at(11) == '1'))
+		t->acr = max(t->mcr,(int)min((double)ecr,t->acr * (1 - t->rdf)));
+}
+	
+
+int AAL5::allowable_cell_cnt() {
+
+	Tcl &tcl = Tcl::instance();
+
+	AtmTrafprm *t = reassembly->txtp;
+	double pt = prev_time;
+	double curr_time = Scheduler::instance().clock();
+
+	if (prev_time > curr_time)
+		tcl.resultf("Scheduler is running backwards in time\n");
+
+	prev_time = curr_time;
+	return (int)((curr_time - pt) * t->acr);
+}
+
+void AAL5::reverse_addresses_for_brm(Packet *p) {
+
+
+	hdr_ip *iph = hdr_ip::access(p);
+	hdr_ip *orig = iph;
+
+        printf("AAL5::src = %d, dst = %d\n", iph->saddr(),iph->daddr());
+
+        int temp_addr = orig->saddr();
+        int temp_port = orig->sport();
+
+	iph->saddr() = orig->daddr();
+	iph->sport() = orig->dport();
+	iph->daddr() = temp_addr; 
+	iph->dport() = temp_port;
+
+        printf("AAL5::new src = %d, new dst = %d\n", iph->saddr(),iph->daddr());
+}
+
+
diff -urN ns-2.1b9/atm/aal.cc~ ns-allinone-2.1b9/ns-2.1b9/atm/aal.cc~
--- ns-2.1b9/atm/aal.cc~	Wed Dec 31 19:00:00 1969
+++ ns-allinone-2.1b9/ns-2.1b9/atm/aal.cc~	Fri Jul 12 15:06:41 2002
@@ -0,0 +1,294 @@
+/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
+/*
+ * Copyright (c) 2000 Regents of the University of New Hampshire.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the MASH Research
+ *      Group at the University of California Berkeley.
+ * 4. Neither the name of the University nor of the Research Group may be
+ *    used to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * 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.
+ *
+ * @(#) $Header: /opt/src/mash/repository/vint/ns-2/cell.h,v 1.0 2000/08/15 10:37 sow Exp $
+ *
+ * Contributed by Sowmya Manjanatha, Dept. of Computer Science, UNH, August 2000 
+ */
+
+#include "aal.h"
+#include "ip.h"
+#include <list>
+#include <stl.h>
+#include <vector>
+
+static class AAL5Class : public TclClass {
+public:
+	AAL5Class() : TclClass("AAL5") {}
+	TclObject* create(int, const char*const*) {
+		return (new AAL5());
+		
+	}	
+} class_aal5;
+
+
+
+Packet **AAL5::segment(Packet *p) {
+
+	int size = hdr_cmn::access(p)->size_ + 8;
+	
+	aal_uid = 0;
+	int x = size % 48;
+        size += (48 - x);
+
+	reassembly->tx_cell_cnt = size/48;
+	Packet *cell[2000];
+
+	for (int i = 0; i < reassembly->tx_cell_cnt; i++) {
+		cell[i] = Packet::alloc();
+                hdr_atm *atmh = hdr_atm::access(cell[i]);
+                atmh->packet = p;
+		initpkt(cell[i]);
+		atmh->vpi = reassembly->vpi;
+		atmh->vci = reassembly->vci;
+		
+		strcpy(atmh->switcher_,"");
+		cell[i]->set_atm();
+
+		if (i == (reassembly->tx_cell_cnt - 1)) {
+			atmh->type = LAST_CELL;
+		}
+		else 
+			atmh->type = 0;
+	}
+	     
+     return cell;
+
+}
+
+int AAL5::command(int argc, const char*const* argv) {
+
+       return (TclObject::command(argc,argv));
+
+}
+
+void AAL5::set_parameters(Reassembly *r, string type) {
+
+	reassembly = r;
+	aal_type_ = type;
+}
+
+void AAL5::initpkt(Packet *p) 
+{
+	char buffer[20];
+
+	hdr_cmn* ch = hdr_cmn::access(p);
+	hdr_atm *atmh = hdr_atm::access(p);
+	hdr_ip *iph = hdr_ip::access(p);
+
+	hdr_ip *orig = hdr_ip::access(atmh->packet);
+
+
+	ch->uid() = aal_uid++;
+
+	ch->ptype() = PT_ATM;
+	ch->size() = CELLSIZE;
+
+	double local_time = Scheduler::instance().clock();
+
+	ch->timestamp() = (u_int32_t)(SAMPLERATE * local_time);
+	ch->iface() = UNKN_IFACE.value(); // from packet.h (agent is local)
+	ch->direction() = hdr_cmn::NONE;
+	ch->ref_count() = 0;	/* reference count */
+	ch->error() = 0;	/* pkt not corrupt to start with */
+
+	//required to find path of simulation
+	iph->ttl() = 1000000;
+	iph->saddr() = orig->saddr();
+	iph->sport() = orig->sport();
+	iph->daddr() = orig->daddr();
+	iph->dport() = orig->dport();
+
+	
+}
+
+void AAL5::increment() {
+
+	reassembly->tx_cell_cnt++;
+	
+}
+
+void AAL5::rx_increment() {
+
+	reassembly->rx_cell_cnt++;
+	
+}
+
+bool AAL5::cellcount_matches() {
+	
+	if(reassembly->tx_cell_cnt == reassembly->rx_cell_cnt) 
+		return true;
+	   
+	return false;
+}
+	   
+	
+Packet *AAL5::build_frm(Packet *orig) {
+
+
+	hdr_atm *temp = hdr_atm::access(orig);
+	//general elements of an ATM packet (Cell)
+	Packet *p = Packet::alloc();
+	hdr_atm *atmh = hdr_atm::access(p);
+	atmh->packet = orig;
+	initpkt(p);
+	atmh->vpi = reassembly->vpi;
+	atmh->vci = reassembly->vci;
+	atmh->type = 6;         //indicates RM cell
+	p->set_atm();
+	atmh->packet = temp->packet;
+
+	//parameters specific to FRM cell
+
+	string rm = string("00000001");   //protocol identifier for ABR
+
+	//Message type, length = 1 octet
+	(rm).append("0");   //DIR = 0 for frm
+	(rm).append("0");   //cell generated by a source
+	(rm).append("0");   //CI bit by source
+	(rm).append("0");   //NI initial
+	(rm).append("x");   //Req/ACK unused
+	(rm).append("xxx"); //reserved	
+
+
+	//ECR
+	char buf[16];
+	sprintf(buf,"%d", reassembly->txtp->pcr);
+	string s((16 - strlen(buf)),'0');
+	(rm).append(s);
+	(rm).append(buf);
+
+
+	//CCR
+	
+	sprintf(buf,"%d",reassembly->txtp->acr);
+	s = string((16 - strlen(buf)),'0');
+	(rm).append(s);
+	(rm).append(buf);
+
+
+	//MCR
+
+	sprintf(buf,"%d",reassembly->txtp->mcr);
+	s = string((16 - strlen(buf)),'0');
+	(rm).append(s);
+	(rm).append(buf);
+
+	// qlength - unused in ABR
+	s = string(32,'x');
+	(rm).append(s);
+
+	//seq # unused in ABR
+	(rm).append(s);
+
+	//Reserved bits
+	s = string(246,'x');
+	(rm).append(s);
+
+	//CRC
+	s = string(10,'1');
+	(rm).append(s);
+
+	// assign payload
+
+	//	printf("atmh->payload = 0x%x, length = %d\n",atmh->payload,(atmh->payload).length());
+
+	atmh->payload = new string(rm);
+	//atmh->payload.resize(atmh->payload.length() + rm.length());
+	//(atmh->payload).assign(rm);
+
+	return p;
+
+}
+
+void AAL5::adjust_source_rate (Packet *rm) {
+	
+	hdr_atm *atmh = hdr_atm::access(rm);
+	
+	string *s = atmh->payload;
+	AtmTrafprm *t = reassembly->txtp;
+	int ecr = atoi((atmh->payload->substr(16,16)).c_str());
+
+
+	if ((s->at(10) == '0') && (s->at(11) == '0')) {
+		double temp = min((double)t->pcr, t->acr + (t->rif * t->pcr));
+		double temp1 = min((double)ecr,temp);
+		t->acr = (int)(max((double)t->mcr, temp1));
+	}
+
+	else if ((s->at(10) == '1') && (s->at(11) == '0')) 
+		t->acr = max(t->mcr, (int)min((double)ecr,t->acr * (1 - t->rdf)));
+
+	else if ((s->at(10) == '0') && (s->at(11) == '1')) 
+		t->acr = max(t->mcr, min(ecr,t->acr));
+
+	else if ((s->at(10) == '1') && (s->at(11) == '1'))
+		t->acr = max(t->mcr,(int)min((double)ecr,t->acr * (1 - t->rdf)));
+}
+	
+
+int AAL5::allowable_cell_cnt() {
+
+	Tcl &tcl = Tcl::instance();
+
+	AtmTrafprm *t = reassembly->txtp;
+	double pt = prev_time;
+	double curr_time = Scheduler::instance().clock();
+
+	if (prev_time > curr_time)
+		tcl.resultf("Scheduler is running backwards in time\n");
+
+	prev_time = curr_time;
+	return (int)((curr_time - pt) * t->acr);
+}
+
+void AAL5::reverse_addresses_for_brm(Packet *p) {
+
+
+	hdr_ip *iph = hdr_ip::access(p);
+	hdr_ip *orig = iph;
+
+        printf("AAL5::src = %d, dst = %d\n", iph->saddr(),iph->daddr());
+
+        int temp_addr = orig->saddr();
+        int temp_port = orig->sport();
+
+	iph->saddr() = orig->daddr();
+	iph->sport() = orig->dport();
+	iph->daddr() = temp_addr; 
+	iph->dport() = temp_port;
+
+        printf("AAL5::new src = %d, new dst = %d\n", iph->saddr(),iph->daddr());
+}
+
+
diff -urN ns-2.1b9/atm/aal.h ns-allinone-2.1b9/ns-2.1b9/atm/aal.h
--- ns-2.1b9/atm/aal.h	Wed Dec 31 19:00:00 1969
+++ ns-allinone-2.1b9/ns-2.1b9/atm/aal.h	Fri Jul 12 16:14:26 2002
@@ -0,0 +1,105 @@
+/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
+/*
+ * Copyright (c) 2000 Regents of the University of New Hampshire.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the MASH Research
+ *      Group at the University of California Berkeley.
+ * 4. Neither the name of the University nor of the Research Group may be
+ *    used to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * 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.
+ *
+ * @(#) $Header: /opt/src/mash/repository/vint/ns-2/cell.h,v 1.0 2000/07/22 22:46 sow Exp $
+ *
+ * Contributed by Sowmya Manjanatha, Dept. of Computer Science, UNH, July 2000 
+ */
+
+#ifndef __aal_h__
+#define __aal_h__
+
+#include "agent.h"
+#include "packet.h"
+#include "atm.h"
+#include "atmqos.h"
+#include <string>
+#include <math.h>
+#include <vector>
+// #include "general.h"
+
+#define SAMPLERATE 8000
+
+class AAL5 : public TclObject {
+
+public:
+	AAL5() : prev_time(0.0), aal_uid(0)  {reassembly = new Reassembly;}
+	~AAL5() { delete reassembly; }
+	Packet **segment(Packet *p);
+	void initpkt(Packet *p);
+	void set_parameters(Reassembly *r,string);
+	// int is_member(int,int);
+	void increment();
+	void rx_increment();
+        bool cellcount_matches();
+	Reassembly get_reassembly() { return *reassembly; }
+	Packet *build_frm(Packet *);                 // ABR only
+	void adjust_source_rate(Packet *);   // ABR only
+	vector<Packet *> get_abr_buffer() { return abr_buffer; }
+	int allowable_cell_cnt();
+	void store_in_abr_buffer(Packet *p) { abr_buffer.push_back(p); }
+	void set_efci() { efci = true; }
+	bool get_efci() { return efci; }
+	void reverse_addresses_for_brm(Packet *);
+	string aal_type() { return aal_type_;}
+	int abr_buffer_size() { return abr_buffer.size(); }
+	Packet *pop_abr() { 
+		Packet *p;
+
+		if (abr_buffer.size() > 0) {
+			p = (Packet *)(*abr_buffer.begin());
+			abr_buffer.erase(abr_buffer.begin());
+			return p;
+		}
+
+		return (Packet *)NULL;
+	}
+
+protected:
+	int command(int argc, const char*const* argv);
+	
+private:
+	Reassembly *reassembly;
+	double prev_time;
+	vector<Packet *> abr_buffer;
+	bool efci;
+	int aal_uid;
+	string aal_type_;
+
+};
+
+
+#endif
+
+
+
diff -urN ns-2.1b9/atm/atm.cc ns-allinone-2.1b9/ns-2.1b9/atm/atm.cc
--- ns-2.1b9/atm/atm.cc	Wed Dec 31 19:00:00 1969
+++ ns-allinone-2.1b9/ns-2.1b9/atm/atm.cc	Fri Jul 12 15:06:41 2002
@@ -0,0 +1,70 @@
+/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
+/*
+ * Copyright (c) 2000 Regents of the University of New Hampshire.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the MASH Research
+ *      Group at the University of California Berkeley.
+ * 4. Neither the name of the University nor of the Research Group may be
+ *    used to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * 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.
+ *
+ * @(#) $Header: /opt/src/mash/repository/vint/ns-2/cell.h,v 1.0 2000/08/28 07:19 sow Exp $
+ *
+ * Contributed by Sowmya Manjanatha, CNRG, University of New Hampshire, August 2000 
+ */
+
+#include <ctype.h>
+#include "atm.h"
+
+
+int hdr_atm::offset_;
+
+static class ATMHeaderClass : public PacketHeaderClass {
+public:
+  ATMHeaderClass() : PacketHeaderClass("PacketHeader/ATM", 
+				       sizeof(hdr_atm)) {
+    bind_offset(&hdr_atm::offset_);
+  }
+} class_atmhdr;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -urN ns-2.1b9/atm/atm.h ns-allinone-2.1b9/ns-2.1b9/atm/atm.h
--- ns-2.1b9/atm/atm.h	Wed Dec 31 19:00:00 1969
+++ ns-allinone-2.1b9/ns-2.1b9/atm/atm.h	Fri Jul 12 15:06:41 2002
@@ -0,0 +1,88 @@
+/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
+/*
+ * Copyright (c) 2000 Regents of the University of New Hampshire.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the MASH Research
+ *      Group at the University of California Berkeley.
+ * 4. Neither the name of the University nor of the Research Group may be
+ *    used to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * 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.
+ *
+ * @(#) $Header: /opt/src/mash/repository/vint/ns-2/cell.h,v 1.0 2000/08/28 07:14 sow Exp $
+ *
+ * Contributed by Sowmya Manjanatha, CNRG, University of New Hampshire, August 2000 
+ */
+
+#ifndef __atm_h__
+#define __atm_h__
+
+#include <string>
+#include "config.h"
+#include "packet.h"
+#include "general.h"
+
+#define CELLSIZE 53
+#define BYTE 8
+#define EFCI 2
+#define EFCI_LAST_CELL 3
+#define EFCI_LAST_UNKNOWN 7
+#define EFCI_FIVE 5
+#define LAST_CELL 1
+#define ATM_NONE 0
+#define ATM_FOUR 4
+#define ATM_RM 6
+
+
+struct hdr_atm {
+	int gfc;
+	int vpi;
+	int vci;
+	int type;
+	bool clp;
+	int hec;
+	string *payload;
+	
+	static int offset_;
+	inline static int &offset() { return offset_; }
+	inline static hdr_atm* access(Packet *p) {
+		return (hdr_atm*) p->access(offset_);
+	}
+	
+	Packet *packet;   /* packet before segmentation */
+	
+	Packet *get_packet() { return packet; } /* original packet : before segmentation */
+	void set_packet(Packet *p) { packet = p;}
+	char switcher_[20];
+};
+
+#endif
+
+
+
+
+
+
+
diff -urN ns-2.1b9/atm/atmconditioner.cc ns-allinone-2.1b9/ns-2.1b9/atm/atmconditioner.cc
--- ns-2.1b9/atm/atmconditioner.cc	Wed Dec 31 19:00:00 1969
+++ ns-allinone-2.1b9/ns-2.1b9/atm/atmconditioner.cc	Fri Jul 12 15:06:41 2002
@@ -0,0 +1,636 @@
+/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
+
+/*
+ * Copyright (c) 1999 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the MASH Research
+ *      Group at the University of California Berkeley.
+ * 4. Neither the name of the University nor of the Research Group may be
+ *    used to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * 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.
+ *
+ * @(#) $Header: /opt/src/mash/repository/vint/ns-2/atmnode.h,v 1.0 2000/06/19 17:35:09 sow Exp $
+ *
+ * Contributed by Sowmya Manjanatha, Dept. of Computer Science, UNH, August 2000 
+ */
+
+#include "atmconditioner.h"
+#include "atmpvc.h"
+#include "ip.h"
+
+static class AtmConditionerClass : public TclClass {
+public:
+	AtmConditionerClass() : TclClass("AtmConditioner") {}
+	TclObject* create(int, const char*const*) {
+		return (new AtmConditioner);
+		
+	}	
+} class_atmconditioner;
+
+
+AtmConditioner::AtmConditioner():qos(0),bucketsize(50000),available_bucket(50000),buffer_limit(50000) 
+{ 
+	bucketlimit = 1000;
+	
+	tx_cells = 0;
+	rx_cells = 0;
+	drops = 0;
+	non_cfm = 0;
+}
+
+
+int AtmConditioner::command(int argc, const char*const* argv) {
+
+
+	if (argc == 2) {
+	  if (strcmp (argv[1], "conditioner_statistics") == 0) {
+		  printf("   %8d      %12d      %5d     %5d     \n",rx_cells,tx_cells,drops,non_cfm);
+	  
+		  return TCL_OK;
+	  }
+	}
+		
+
+	if (argc == 3) {
+		
+		if (strcmp("set-profile",argv[1]) == 0) {
+			return TCL_OK;
+		}
+		
+		if (strcmp("add-pvc_dbase",argv[1]) == 0) {
+			pvc_dbase = (pvc_db *) TclObject::lookup(argv[2]);
+			return TCL_OK;
+		}
+		
+		if (strcmp("total_service_rate_", argv[1]) == 0) {
+			total_service_rate = atof(argv[2]);
+			available_service_rate = total_service_rate;
+			printf("AtmConditioner::cac, avail service rate = %e\n", available_service_rate);
+			
+			if(total_service_rate < 0)
+			  return TCL_ERROR;
+			return TCL_OK;
+		}
+	}
+	
+	return (Connector::command(argc,argv));
+}
+
+/* This is where the cell first enters into the ATM Network.
+   Well, this is because the traffic entering is conditioned
+   upfront given to the fact that the AtmConditioner is installed
+   between a link and a node. */
+
+
+void AtmConditioner::recv(Packet *p, Handler *h) {
+
+	int idx;
+
+  /* Here I follow a strict allocation procedure. 
+     If traffic is conforming, I allocate, else I drop */
+
+	hdr_atm *atmh = hdr_atm::access(p);
+
+        AtmQos *qos = classify(p);
+
+	rx_cells++;
+
+	if (qos == NULL) {
+		printf("AtmConditioner :: qos is NULL, dropping packet\n");
+		drops++;
+		drop(p);
+	}
+
+	
+	else
+		{
+			switch (qos->get_rxtp()->traffic_class) {
+				
+			case CBR:
+			case rt_VBR:
+			case nrt_VBR:
+		//		store_cell(p);
+				usage_parameter_control(p,h);   
+				
+				break;
+			case GFR:
+				gfr_upc(p,h);
+			case ABR:
+			case UBR:
+				// traffic_shaping(p,h,(double)1/bucketrate);
+
+				//				printf("AtmConditioner:: sending packet to target, vpi/vci = %d/%d, type = %d\n",atmh->vpi,atmh->vci,atmh->type);
+				tx_cells++;
+				target_->recv(p,h);
+				break;
+			}
+
+		}
+}
+
+/* here again, I haven't worried about incoming PVC or rxtps.  
+   I haven't the slightest idea where to find information re:
+   their significance. */
+
+void AtmConditioner::usage_parameter_control(Packet *p,Handler *h) {
+
+	Tcl &tcl = Tcl::instance();
+	double T;
+	bool conforms;
+        int type;
+
+	AtmQos *qos = classify(p);
+
+        if (qos == NULL) {
+		drops++;
+		drop(p);
+		return;
+         }
+
+        type = qos->get_rxtp()->traffic_class;
+	
+	
+	switch (type) {
+		
+	case CBR: 
+		{
+			int pcr = qos->get_rxtp()->pcr;
+			T = (double) (1.0/(double)pcr);
+			
+			conforms = gcra(T,qos->get_rxtp()->cdvt, qos);
+			upc_helper(conforms,p,h); 
+			
+		}
+		break;
+		
+	case rt_VBR:
+	case nrt_VBR:
+		{
+			double Ts = (double)(1.0/(double)(qos->get_rxtp()->scr));
+			T = (double) (1.0/(double)(qos->get_rxtp()->pcr));
+			double tau_s = qos->get_rxtp()->cdvt;
+			int mbs = qos->get_rxtp()->mbs;
+			
+			double tau = (mbs - 1)*(Ts - T);
+			conforms = gcra(Ts,(tau+tau_s),qos);
+			upc_helper(conforms,p,h);
+		}
+		break;
+	default: 
+		tcl.resultf("invalid service category %d\n",type);
+		break;
+		
+			
+	}
+
+
+}
+
+bool AtmConditioner::gcra(double T, double tau, AtmQos *qos) {
+
+
+	double tat = qos->get_rxtp()->tat;
+
+	/* the first cell on the connection */
+	if (tat == -1) {
+		qos->get_rxtp()->tat = Scheduler::instance().clock() + T;
+		return true;
+	}
+	
+	double temp = Scheduler::instance().clock();
+
+
+	/* conforming */
+	if (temp >= tat) {
+		qos->get_rxtp()->tat += T;
+		return true;
+	}
+
+	else if ((temp < tat) && (tat <= (temp+tau))) {
+		qos->get_rxtp()->tat = temp+T;
+		return true;
+	}
+
+	else if (temp < (tat - tau)) {
+                non_cfm++;
+		return false;
+        }
+
+	return false;
+}
+		
+		
+		
+	
+/* iat stands for interarrival time */
+// void AtmConditioner::traffic_shaping(Packet *p, Handler *h, double iat) {
+
+//	update_tokens(iat);
+
+	/* actual shaping function */
+
+	/* if the bucketsize > 0 and buffer is not empty, 
+           the bucket must have been updated in this run of
+           traffic shaping function */
+
+//	if (bucketsize > 0) {
+		
+/*		if (buffer.size() > 0) {
+		
+			do {
+				bucketsize--;
+				printf("AtmConditioner: %s sending packet to target\n",name());
+				target_->recv(buffer.front(),h);
+			} while ((buffer.size() > 0) && (bucketsize > 0));
+		
+			} */
+		/* sufficient time to collect another token might
+                   have elapsed after the while loop */
+		
+/*		if (bucketsize > 0) {
+			printf("AtmConditioner: %s sending packet to target\n",name());
+			target_->recv(p,h);
+			bucketsize--;
+		} else {
+			if (buffer_limit >= buffer.size())
+				{
+					printf("AtmConditioner::dropping, time = %e\n", Scheduler::instance().clock());
+					drop(p);
+				}
+			else
+				buffer.push_back(p);
+		}
+		
+	}
+	
+	else {
+		
+		if (buffer_limit >= buffer.size()) {
+			printf("AtmConditioner::dropping packet, time = %e\n", Scheduler::instance().clock());
+			drop(p);
+		}
+		else
+			buffer.push_back(p);
+	}
+
+	} */
+	 
+/* connection admission control */
+bool AtmConditioner::cac(path pth, int linknum) {
+
+	AtmTrafprm *txtp = pth.outgoing_pvc.get_txtp();
+
+	// transmit side parameter check
+	
+	Tcl &tcl = Tcl::instance();
+
+	switch (txtp->traffic_class) {
+
+	case CBR:
+		/* for now, I am just considering conditioning on
+                   the outgoing PVC and also only the transmit
+                   traffic descriptor information.  I will have
+                   to find out the significance of the rx traffic
+                   descriptor as well as the incoming pvc */
+
+		if ((txtp->pcr * CELLSIZE * BYTE) >= pvc_dbase->avail_rate(linknum)) {
+			return false;
+		}
+		else {
+			pvc_dbase->set_avail_rate((txtp->pcr) * CELLSIZE * BYTE,linknum);
+			return true;
+		}
+		
+		break;
+
+	case rt_VBR:
+
+
+		if ((CELLSIZE * BYTE *((1+A1)*txtp->scr)) >= pvc_dbase->avail_rate(linknum)) {
+
+			printf("AtmCond::cac, requested rate = %e,scr = %d\n",CELLSIZE*BYTE*((1+A1)*txtp->scr),txtp->scr);
+			return false;
+		}
+		else {
+			pvc_dbase->set_avail_rate( (txtp->scr) * CELLSIZE * BYTE,linknum);
+			return true;
+		}
+		break;
+
+	case nrt_VBR:
+
+		if ((txtp->scr * CELLSIZE * BYTE )>= pvc_dbase->avail_rate(linknum))
+			return false;
+		else {
+			pvc_dbase->set_avail_rate((txtp->scr) * CELLSIZE * BYTE,linknum);
+			return true;
+		}
+
+		break;
+
+	case ABR:
+	case GFR:
+
+		if ((txtp->mcr * CELLSIZE * BYTE) >= pvc_dbase->avail_rate(linknum))
+			return false;
+		else {
+			pvc_dbase->set_avail_rate((txtp->mcr) * CELLSIZE * BYTE,linknum);
+			return true;
+		}
+		break;
+
+	case UBR:
+		break;
+
+	default:
+		tcl.resultf("unknown ATM traffic class");
+	}
+	return true;
+}
+
+AtmQos *AtmConditioner::classify(Packet *p) {
+
+	hdr_atm *atmh = hdr_atm::access(p);
+
+	return pvc_dbase->incoming_qos_lookup(atmh->vpi,atmh->vci);
+}
+
+
+
+
+void AtmConditioner::upc_helper_old(bool conforms, Packet *p, Handler *h) 
+{
+	hdr_atm *atmh = hdr_atm::access(p);
+	Tcl &tcl = Tcl::instance();
+
+	int idx = find_bucket(p);
+
+	if (conforms && ((atmh->clp == 0) || (atmh->clp == 1))) 
+		{
+			
+			if (idx  < 0) {
+				tcl.resultf("AtmConditioner::traffic unprovisioned");
+				return;
+			}
+				
+
+			if (leakybucket[idx]->size() > 0) {
+				Packet *temp = leakybucket[idx]->first();
+				leakybucket[idx]->erase();
+				tx_cells++;
+				target_->recv(temp,h);
+			}
+			// traffic_shaping(leakybucket[idx]->first(),h,(double)1/bucketrate);
+
+		}
+	
+	else if (!conforms && (atmh->clp == 0)) {
+		atmh->clp = 1;
+	}
+	
+	else if (!conforms && (atmh->clp == 1)) {
+		//	printf("AtmConditioner :: ID %s dropping packet at %e\n",name(),Scheduler::instance().clock());
+		drops++;
+		drop(leakybucket[idx]->first());
+		leakybucket[idx]->erase();
+	}
+	
+}
+
+
+/* since NS is a single thread simulator, tokens into a bucket cannot
+   be generated parallely without being interrupted by other tasks.
+   Therefore, I use an approximation to the token generation concept.
+
+   I maintain a time variable that is basically the time at which the
+   previous token was generated.  The floor or integer value of
+   elapsed_time/token_bucket_rate gives the number of tokens that must
+   be input into the bucket. */
+
+ void AtmConditioner::update_tokens (double iat) {
+	
+	 double temp = Scheduler::instance().clock();
+	 double elapsed_time = temp - last_token_update_time;
+	 last_token_update_time = temp;
+	 
+	 bucketsize += (int)(elapsed_time/iat);
+ }
+
+
+ int AtmConditioner::find_bucket(Packet *p)
+	 {
+
+		 hdr_atm *atmh = hdr_atm::access(p);
+
+		 for (unsigned int i = 0; i < leakybucket.size(); i++)
+			 {
+				 int vp = (int)leakybucket[i]->vpi();
+				 int vc = (int)leakybucket[i]->vci();
+				 
+				 if ((vp == atmh->vpi) && (vc == atmh->vci))
+					 return i;
+			 }
+
+		 return -1;
+	 }
+				 
+ void AtmConditioner::store_cell(Packet *p)
+	 {
+
+		 int idx = find_bucket(p);
+		 hdr_atm *atmh = hdr_atm::access(p);
+
+		 if (idx > -1) {
+			 if (leakybucket[idx]->size() < bucketlimit)
+				 leakybucket[idx]->push_back(p);
+			 
+			 else {
+				 drops++;
+				 drop(p);
+			 }
+		 }
+		 else {
+			 VCBuffer *l = new VCBuffer(atmh->vpi,atmh->vci);
+			 leakybucket.push_back(l);
+			 leakybucket[leakybucket.size() - 1]->push_back(p);
+
+		 }
+		 
+		 return;
+	 }
+
+char *decode_type(int type)
+{
+	if (type == CBR)
+		return "CBR";
+	
+	else if (type == rt_VBR)
+		return "rt-VBR";
+
+	else if (type == nrt_VBR)
+		return "nrt-VBR";
+
+	else if (type == GFR)
+		return "GFR";
+
+	else if (type == ABR)
+		return "ABR";
+
+	else if (type == UBR)
+		return "UBR";
+
+	else
+		return "UNKNOWN";
+}
+
+// the policing for gfr is frame based and hence the calculations 
+// vary from normal gcra.
+
+void AtmConditioner::gfr_upc(Packet *p, Handler *h) {
+
+	bool clp  = gfr_clp(p);
+	bool gcra = f_gcra(p);
+	bool mfs  = gfr_mfs(p);
+
+	if (gcra && mfs && clp) {
+		tx_cells++;
+		target_->recv(p,h);
+	}
+
+	else {
+		drops++;
+		drop(p);
+	}
+
+	return;
+}
+
+
+// frame based gcra
+
+bool AtmConditioner::f_gcra(Packet *p) {
+
+	hdr_atm *atmh = hdr_atm::access(p);
+	
+	AtmQos *qos = classify(p);
+        AtmTrafprm *rxtp  = qos->get_rxtp();
+
+	double T = 1/(rxtp->mcr);
+	double BT = ((rxtp->mbs) - 1)*((1/rxtp->mcr) - (1/rxtp->pcr));
+	double L = BT + rxtp->cdvt;
+
+	printf("%e  %e    %e 0x%x\n",T,BT,L,atmh);
+
+
+	return gcra(T,BT+rxtp->cdvt,qos);
+}
+
+
+bool AtmConditioner::gfr_mfs(Packet *p) {
+
+	hdr_atm *atmh = hdr_atm::access(p);
+	AtmTrafprm *rxtp = classify(p)->get_rxtp();
+	int gfr_idx = find_gfr_cell_cnt(atmh->vpi, atmh->vci);
+	int gcnt = gfr_cells_per_vc[gcnt].gfr_cells;
+
+	if (( ((atmh->type%2) != 1) && (rxtp->mfs > gcnt)) || (atmh->type%2 == 1))
+		{
+			gfr_cells_per_vc[gfr_idx].gfr_cells++;
+			return true;
+		}
+
+	return false;
+}
+
+
+bool AtmConditioner::gfr_clp(Packet *p) {
+
+	hdr_atm *atmh = hdr_atm::access(p);
+
+	int idx = find_gfr_cell_cnt(atmh->vpi,atmh->vci);
+
+	// this is the first cell on the vc
+	if (idx == -1) {
+		gfr_info info = gfr_info(atmh->vpi, atmh->vci, atmh->clp);
+		gfr_cells_per_vc.push_back(info);
+	}
+
+
+	else {
+		if (atmh->clp == gfr_cells_per_vc[idx].clp)
+			return true;
+		return false;
+	}
+		
+	return false;
+}
+
+
+int AtmConditioner::find_gfr_cell_cnt(int vpi, int vci) {
+
+	for(int i=0; i < gfr_cells_per_vc.size() ; i++) {
+		int vp = gfr_cells_per_vc[i].vpi;
+		int vc = gfr_cells_per_vc[i].vci;
+
+		if ((vp == vpi) && (vc == vci))
+			return i;
+	}
+
+	return -1;
+}
+
+
+void AtmConditioner::upc_helper(bool conforms,Packet *p, Handler *h) {
+
+         int idx = find_bucket(p);
+         hdr_atm *atmh = hdr_atm::access(p);
+
+
+         if (conforms) {
+                if (idx < 0) {
+                      tx_cells++;
+                      target_->recv(p,h);
+                }
+
+
+                else {
+                    Packet *c = (Packet *)leakybucket[idx]->first();
+                    leakybucket[idx]->erase();
+                    store_cell(p);
+                    tx_cells++;
+                    target_->recv(c,h);
+                }
+           }
+
+           else {
+
+                store_cell(p);
+             }
+
+
+}
+
+
diff -urN ns-2.1b9/atm/atmconditioner.cc.0326 ns-allinone-2.1b9/ns-2.1b9/atm/atmconditioner.cc.0326
--- ns-2.1b9/atm/atmconditioner.cc.0326	Wed Dec 31 19:00:00 1969
+++ ns-allinone-2.1b9/ns-2.1b9/atm/atmconditioner.cc.0326	Fri Jul 12 15:06:41 2002
@@ -0,0 +1,636 @@
+/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
+
+/*
+ * Copyright (c) 1999 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the MASH Research
+ *      Group at the University of California Berkeley.
+ * 4. Neither the name of the University nor of the Research Group may be
+ *    used to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * 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.
+ *
+ * @(#) $Header: /opt/src/mash/repository/vint/ns-2/atmnode.h,v 1.0 2000/06/19 17:35:09 sow Exp $
+ *
+ * Contributed by Sowmya Manjanatha, Dept. of Computer Science, UNH, August 2000 
+ */
+
+#include "atmconditioner.h"
+#include "atmpvc.h"
+#include "ip.h"
+
+static class AtmConditionerClass : public TclClass {
+public:
+	AtmConditionerClass() : TclClass("AtmConditioner") {}
+	TclObject* create(int, const char*const*) {
+		return (new AtmConditioner);
+		
+	}	
+} class_atmconditioner;
+
+
+AtmConditioner::AtmConditioner():qos(0),bucketsize(50000),available_bucket(50000),buffer_limit(50000) 
+{ 
+	bucketlimit = 2000;
+	
+	tx_cells = 0;
+	rx_cells = 0;
+	drops = 0;
+	non_cfm = 0;
+}
+
+
+int AtmConditioner::command(int argc, const char*const* argv) {
+
+
+	if (argc == 2) {
+	  if (strcmp (argv[1], "conditioner_statistics") == 0) {
+		  printf("   %8d      %12d      %5d     %5d     \n",rx_cells,tx_cells,drops,non_cfm);
+	  
+		  return TCL_OK;
+	  }
+	}
+		
+
+	if (argc == 3) {
+		
+		if (strcmp("set-profile",argv[1]) == 0) {
+			return TCL_OK;
+		}
+		
+		if (strcmp("add-pvc_dbase",argv[1]) == 0) {
+			pvc_dbase = (pvc_db *) TclObject::lookup(argv[2]);
+			return TCL_OK;
+		}
+		
+		if (strcmp("total_service_rate_", argv[1]) == 0) {
+			total_service_rate = atof(argv[2]);
+			available_service_rate = total_service_rate;
+			printf("AtmConditioner::cac, avail service rate = %e\n", available_service_rate);
+			
+			if(total_service_rate < 0)
+			  return TCL_ERROR;
+			return TCL_OK;
+		}
+	}
+	
+	return (Connector::command(argc,argv));
+}
+
+/* This is where the cell first enters into the ATM Network.
+   Well, this is because the traffic entering is conditioned
+   upfront given to the fact that the AtmConditioner is installed
+   between a link and a node. */
+
+
+void AtmConditioner::recv(Packet *p, Handler *h) {
+
+	int idx;
+
+  /* Here I follow a strict allocation procedure. 
+     If traffic is conforming, I allocate, else I drop */
+
+	hdr_atm *atmh = hdr_atm::access(p);
+
+        AtmQos *qos = classify(p);
+
+	rx_cells++;
+
+	if (qos == NULL) {
+		printf("AtmConditioner :: qos is NULL, dropping packet\n");
+		drops++;
+		drop(p);
+	}
+
+	
+	else
+		{
+			switch (qos->get_rxtp()->traffic_class) {
+				
+			case CBR:
+			case rt_VBR:
+			case nrt_VBR:
+		//		store_cell(p);
+				usage_parameter_control(p,h);   
+				
+				break;
+			case GFR:
+				gfr_upc(p,h);
+			case ABR:
+			case UBR:
+				// traffic_shaping(p,h,(double)1/bucketrate);
+
+				//				printf("AtmConditioner:: sending packet to target, vpi/vci = %d/%d, type = %d\n",atmh->vpi,atmh->vci,atmh->type);
+				tx_cells++;
+				target_->recv(p,h);
+				break;
+			}
+
+		}
+}
+
+/* here again, I haven't worried about incoming PVC or rxtps.  
+   I haven't the slightest idea where to find information re:
+   their significance. */
+
+void AtmConditioner::usage_parameter_control(Packet *p,Handler *h) {
+
+	Tcl &tcl = Tcl::instance();
+	double T;
+	bool conforms;
+        int type;
+
+	AtmQos *qos = classify(p);
+
+        if (qos == NULL) {
+		drops++;
+		drop(p);
+		return;
+         }
+
+        type = qos->get_rxtp()->traffic_class;
+	
+	
+	switch (type) {
+		
+	case CBR: 
+		{
+			int pcr = qos->get_rxtp()->pcr;
+			T = (double) (1.0/(double)pcr);
+			
+			conforms = gcra(T,qos->get_rxtp()->cdvt, qos);
+			upc_helper(conforms,p,h); 
+			
+		}
+		break;
+		
+	case rt_VBR:
+	case nrt_VBR:
+		{
+			double Ts = (double)(1.0/(double)(qos->get_rxtp()->scr));
+			T = (double) (1.0/(double)(qos->get_rxtp()->pcr));
+			double tau_s = qos->get_rxtp()->cdvt;
+			int mbs = qos->get_rxtp()->mbs;
+			
+			double tau = (mbs - 1)*(Ts - T);
+			conforms = gcra(Ts,(tau+tau_s),qos);
+			upc_helper(conforms,p,h);
+		}
+		break;
+	default: 
+		tcl.resultf("invalid service category %d\n",type);
+		break;
+		
+			
+	}
+
+
+}
+
+bool AtmConditioner::gcra(double T, double tau, AtmQos *qos) {
+
+
+	double tat = qos->get_rxtp()->tat;
+
+	/* the first cell on the connection */
+	if (tat == -1) {
+		qos->get_rxtp()->tat = Scheduler::instance().clock() + T;
+		return true;
+	}
+	
+	double temp = Scheduler::instance().clock();
+
+
+	/* conforming */
+	if (temp >= tat) {
+		qos->get_rxtp()->tat += T;
+		return true;
+	}
+
+	else if ((temp < tat) && (tat <= (temp+tau))) {
+		qos->get_rxtp()->tat = temp+T;
+		return true;
+	}
+
+	else if (temp < (tat - tau)) {
+                non_cfm++;
+		return false;
+        }
+
+	return false;
+}
+		
+		
+		
+	
+/* iat stands for interarrival time */
+// void AtmConditioner::traffic_shaping(Packet *p, Handler *h, double iat) {
+
+//	update_tokens(iat);
+
+	/* actual shaping function */
+
+	/* if the bucketsize > 0 and buffer is not empty, 
+           the bucket must have been updated in this run of
+           traffic shaping function */
+
+//	if (bucketsize > 0) {
+		
+/*		if (buffer.size() > 0) {
+		
+			do {
+				bucketsize--;
+				printf("AtmConditioner: %s sending packet to target\n",name());
+				target_->recv(buffer.front(),h);
+			} while ((buffer.size() > 0) && (bucketsize > 0));
+		
+			} */
+		/* sufficient time to collect another token might
+                   have elapsed after the while loop */
+		
+/*		if (bucketsize > 0) {
+			printf("AtmConditioner: %s sending packet to target\n",name());
+			target_->recv(p,h);
+			bucketsize--;
+		} else {
+			if (buffer_limit >= buffer.size())
+				{
+					printf("AtmConditioner::dropping, time = %e\n", Scheduler::instance().clock());
+					drop(p);
+				}
+			else
+				buffer.push_back(p);
+		}
+		
+	}
+	
+	else {
+		
+		if (buffer_limit >= buffer.size()) {
+			printf("AtmConditioner::dropping packet, time = %e\n", Scheduler::instance().clock());
+			drop(p);
+		}
+		else
+			buffer.push_back(p);
+	}
+
+	} */
+	 
+/* connection admission control */
+bool AtmConditioner::cac(path pth, int linknum) {
+
+	AtmTrafprm *txtp = pth.outgoing_pvc.get_txtp();
+
+	// transmit side parameter check
+	
+	Tcl &tcl = Tcl::instance();
+
+	switch (txtp->traffic_class) {
+
+	case CBR:
+		/* for now, I am just considering conditioning on
+                   the outgoing PVC and also only the transmit
+                   traffic descriptor information.  I will have
+                   to find out the significance of the rx traffic
+                   descriptor as well as the incoming pvc */
+
+		if ((txtp->pcr * CELLSIZE * BYTE) >= pvc_dbase->avail_rate(linknum)) {
+			return false;
+		}
+		else {
+			pvc_dbase->set_avail_rate((txtp->pcr) * CELLSIZE * BYTE,linknum);
+			return true;
+		}
+		
+		break;
+
+	case rt_VBR:
+
+
+		if ((CELLSIZE * BYTE *((1+A1)*txtp->scr)) >= pvc_dbase->avail_rate(linknum)) {
+
+			printf("AtmCond::cac, requested rate = %e,scr = %d\n",CELLSIZE*BYTE*((1+A1)*txtp->scr),txtp->scr);
+			return false;
+		}
+		else {
+			pvc_dbase->set_avail_rate( (txtp->scr) * CELLSIZE * BYTE,linknum);
+			return true;
+		}
+		break;
+
+	case nrt_VBR:
+
+		if ((txtp->scr * CELLSIZE * BYTE )>= pvc_dbase->avail_rate(linknum))
+			return false;
+		else {
+			pvc_dbase->set_avail_rate((txtp->scr) * CELLSIZE * BYTE,linknum);
+			return true;
+		}
+
+		break;
+
+	case ABR:
+	case GFR:
+
+		if ((txtp->mcr * CELLSIZE * BYTE) >= pvc_dbase->avail_rate(linknum))
+			return false;
+		else {
+			pvc_dbase->set_avail_rate((txtp->mcr) * CELLSIZE * BYTE,linknum);
+			return true;
+		}
+		break;
+
+	case UBR:
+		break;
+
+	default:
+		tcl.resultf("unknown ATM traffic class");
+	}
+	return true;
+}
+
+AtmQos *AtmConditioner::classify(Packet *p) {
+
+	hdr_atm *atmh = hdr_atm::access(p);
+
+	return pvc_dbase->incoming_qos_lookup(atmh->vpi,atmh->vci);
+}
+
+
+
+
+void AtmConditioner::upc_helper_old(bool conforms, Packet *p, Handler *h) 
+{
+	hdr_atm *atmh = hdr_atm::access(p);
+	Tcl &tcl = Tcl::instance();
+
+	int idx = find_bucket(p);
+
+	if (conforms && ((atmh->clp == 0) || (atmh->clp == 1))) 
+		{
+			
+			if (idx  < 0) {
+				tcl.resultf("AtmConditioner::traffic unprovisioned");
+				return;
+			}
+				
+
+			if (leakybucket[idx]->size() > 0) {
+				Packet *temp = leakybucket[idx]->first();
+				leakybucket[idx]->erase();
+				tx_cells++;
+				target_->recv(temp,h);
+			}
+			// traffic_shaping(leakybucket[idx]->first(),h,(double)1/bucketrate);
+
+		}
+	
+	else if (!conforms && (atmh->clp == 0)) {
+		atmh->clp = 1;
+	}
+	
+	else if (!conforms && (atmh->clp == 1)) {
+		//	printf("AtmConditioner :: ID %s dropping packet at %e\n",name(),Scheduler::instance().clock());
+		drops++;
+		drop(leakybucket[idx]->first());
+		leakybucket[idx]->erase();
+	}
+	
+}
+
+
+/* since NS is a single thread simulator, tokens into a bucket cannot
+   be generated parallely without being interrupted by other tasks.
+   Therefore, I use an approximation to the token generation concept.
+
+   I maintain a time variable that is basically the time at which the
+   previous token was generated.  The floor or integer value of
+   elapsed_time/token_bucket_rate gives the number of tokens that must
+   be input into the bucket. */
+
+ void AtmConditioner::update_tokens (double iat) {
+	
+	 double temp = Scheduler::instance().clock();
+	 double elapsed_time = temp - last_token_update_time;
+	 last_token_update_time = temp;
+	 
+	 bucketsize += (int)(elapsed_time/iat);
+ }
+
+
+ int AtmConditioner::find_bucket(Packet *p)
+	 {
+
+		 hdr_atm *atmh = hdr_atm::access(p);
+
+		 for (unsigned int i = 0; i < leakybucket.size(); i++)
+			 {
+				 int vp = (int)leakybucket[i]->vpi();
+				 int vc = (int)leakybucket[i]->vci();
+				 
+				 if ((vp == atmh->vpi) && (vc == atmh->vci))
+					 return i;
+			 }
+
+		 return -1;
+	 }
+				 
+ void AtmConditioner::store_cell(Packet *p)
+	 {
+
+		 int idx = find_bucket(p);
+		 hdr_atm *atmh = hdr_atm::access(p);
+
+		 if (idx > -1) {
+			 if (leakybucket[idx]->size() < bucketlimit)
+				 leakybucket[idx]->push_back(p);
+			 
+			 else {
+				 drops++;
+				 drop(p);
+			 }
+		 }
+		 else {
+			 VCBuffer *l = new VCBuffer(atmh->vpi,atmh->vci);
+			 leakybucket.push_back(l);
+			 leakybucket[leakybucket.size() - 1]->push_back(p);
+
+		 }
+		 
+		 return;
+	 }
+
+char *decode_type(int type)
+{
+	if (type == CBR)
+		return "CBR";
+	
+	else if (type == rt_VBR)
+		return "rt-VBR";
+
+	else if (type == nrt_VBR)
+		return "nrt-VBR";
+
+	else if (type == GFR)
+		return "GFR";
+
+	else if (type == ABR)
+		return "ABR";
+
+	else if (type == UBR)
+		return "UBR";
+
+	else
+		return "UNKNOWN";
+}
+
+// the policing for gfr is frame based and hence the calculations 
+// vary from normal gcra.
+
+void AtmConditioner::gfr_upc(Packet *p, Handler *h) {
+
+	bool clp  = gfr_clp(p);
+	bool gcra = f_gcra(p);
+	bool mfs  = gfr_mfs(p);
+
+	if (gcra && mfs && clp) {
+		tx_cells++;
+		target_->recv(p,h);
+	}
+
+	else {
+		drops++;
+		drop(p);
+	}
+
+	return;
+}
+
+
+// frame based gcra
+
+bool AtmConditioner::f_gcra(Packet *p) {
+
+	hdr_atm *atmh = hdr_atm::access(p);
+	
+	AtmQos *qos = classify(p);
+        AtmTrafprm *rxtp  = qos->get_rxtp();
+
+	double T = 1/(rxtp->mcr);
+	double BT = ((rxtp->mbs) - 1)*((1/rxtp->mcr) - (1/rxtp->pcr));
+	double L = BT + rxtp->cdvt;
+
+	printf("%e  %e    %e 0x%x\n",T,BT,L,atmh);
+
+
+	return gcra(T,BT+rxtp->cdvt,qos);
+}
+
+
+bool AtmConditioner::gfr_mfs(Packet *p) {
+
+	hdr_atm *atmh = hdr_atm::access(p);
+	AtmTrafprm *rxtp = classify(p)->get_rxtp();
+	int gfr_idx = find_gfr_cell_cnt(atmh->vpi, atmh->vci);
+	int gcnt = gfr_cells_per_vc[gcnt].gfr_cells;
+
+	if (( ((atmh->type%2) != 1) && (rxtp->mfs > gcnt)) || (atmh->type%2 == 1))
+		{
+			gfr_cells_per_vc[gfr_idx].gfr_cells++;
+			return true;
+		}
+
+	return false;
+}
+
+
+bool AtmConditioner::gfr_clp(Packet *p) {
+
+	hdr_atm *atmh = hdr_atm::access(p);
+
+	int idx = find_gfr_cell_cnt(atmh->vpi,atmh->vci);
+
+	// this is the first cell on the vc
+	if (idx == -1) {
+		gfr_info info = gfr_info(atmh->vpi, atmh->vci, atmh->clp);
+		gfr_cells_per_vc.push_back(info);
+	}
+
+
+	else {
+		if (atmh->clp == gfr_cells_per_vc[idx].clp)
+			return true;
+		return false;
+	}
+		
+	return false;
+}
+
+
+int AtmConditioner::find_gfr_cell_cnt(int vpi, int vci) {
+
+	for(int i=0; i < gfr_cells_per_vc.size() ; i++) {
+		int vp = gfr_cells_per_vc[i].vpi;
+		int vc = gfr_cells_per_vc[i].vci;
+
+		if ((vp == vpi) && (vc == vci))
+			return i;
+	}
+
+	return -1;
+}
+
+
+void AtmConditioner::upc_helper(bool conforms,Packet *p, Handler *h) {
+
+         int idx = find_bucket(p);
+         hdr_atm *atmh = hdr_atm::access(p);
+
+
+         if (conforms) {
+                if (idx < 0) {
+                      tx_cells++;
+                      target_->recv(p,h);
+                }
+
+
+                else {
+                    Packet *c = (Packet *)leakybucket[idx]->first();
+                    leakybucket[idx]->erase();
+                    store_cell(p);
+                    tx_cells++;
+                    target_->recv(c,h);
+                }
+           }
+
+           else {
+
+                store_cell(p);
+             }
+
+
+}
+
+
diff -urN ns-2.1b9/atm/atmconditioner.cc.bck ns-allinone-2.1b9/ns-2.1b9/atm/atmconditioner.cc.bck
--- ns-2.1b9/atm/atmconditioner.cc.bck	Wed Dec 31 19:00:00 1969
+++ ns-allinone-2.1b9/ns-2.1b9/atm/atmconditioner.cc.bck	Fri Jul 12 15:06:41 2002
@@ -0,0 +1,642 @@
+/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
+
+/*
+ * Copyright (c) 1999 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the MASH Research
+ *      Group at the University of California Berkeley.
+ * 4. Neither the name of the University nor of the Research Group may be
+ *    used to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * 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.
+ *
+ * @(#) $Header: /opt/src/mash/repository/vint/ns-2/atmnode.h,v 1.0 2000/06/19 17:35:09 sow Exp $
+ *
+ * Contributed by Sowmya Manjanatha, Dept. of Computer Science, UNH, August 2000 
+ */
+
+#include "atmconditioner.h"
+#include "atmpvc.h"
+#include "ip.h"
+
+static class AtmConditionerClass : public TclClass {
+public:
+	AtmConditionerClass() : TclClass("AtmConditioner") {}
+	TclObject* create(int, const char*const*) {
+		return (new AtmConditioner);
+		
+	}	
+} class_atmconditioner;
+
+
+AtmConditioner::AtmConditioner():qos(0),bucketsize(50000),available_bucket(50000),buffer_limit(50000) 
+{ 
+	bucketlimit = 2000;
+	
+	tx_cells = 0;
+	rx_cells = 0;
+	drops = 0;
+}
+
+
+int AtmConditioner::command(int argc, const char*const* argv) {
+
+
+	if (argc == 2) {
+	  if (strcmp (argv[1], "conditioner_statistics") == 0) {
+		  printf("   %8d             %12d               %5d          \n",rx_cells,tx_cells,drops);
+	  
+		  return TCL_OK;
+	  }
+	}
+		
+
+	if (argc == 3) {
+		
+		if (strcmp("set-profile",argv[1]) == 0) {
+			return TCL_OK;
+		}
+		
+		if (strcmp("add-pvc_dbase",argv[1]) == 0) {
+			pvc_dbase = (pvc_db *) TclObject::lookup(argv[2]);
+			return TCL_OK;
+		}
+		
+		if (strcmp("total_service_rate_", argv[1]) == 0) {
+			total_service_rate = atof(argv[2]);
+			available_service_rate = total_service_rate;
+			printf("AtmConditioner::cac, avail service rate = %e\n", available_service_rate);
+			
+			if(total_service_rate < 0)
+			  return TCL_ERROR;
+			return TCL_OK;
+		}
+	}
+	
+	return (Connector::command(argc,argv));
+}
+
+/* This is where the cell first enters into the ATM Network.
+   Well, this is because the traffic entering is conditioned
+   upfront given to the fact that the AtmConditioner is installed
+   between a link and a node. */
+
+
+void AtmConditioner::recv(Packet *p, Handler *h) {
+
+	int idx;
+  /* Here I follow a strict allocation procedure. 
+     If traffic is conforming, I allocate, else I drop */
+
+	hdr_atm *atmh = hdr_atm::access(p);
+
+        AtmQos *qos = classify(p);
+
+	//	printf("AtmConditioner::recv, vpi/vci = %d/%d, type = %d\n", atmh->vpi,atmh->vci,atmh->type);
+	rx_cells++;
+
+	if (qos == NULL) {
+		printf("AtmConditioner :: qos is NULL, dropping packet\n");
+		drops++;
+		drop(p);
+	}
+
+	
+	else
+		{
+			switch (qos->get_rxtp()->traffic_class) {
+				
+			case CBR:
+			case rt_VBR:
+			case nrt_VBR:
+				store_cell(p);
+				usage_parameter_control(p,h);   
+				
+				break;
+			case GFR:
+				gfr_upc(p,h);
+			case ABR:
+			case UBR:
+				// traffic_shaping(p,h,(double)1/bucketrate);
+
+				//				printf("AtmConditioner:: sending packet to target, vpi/vci = %d/%d, type = %d\n",atmh->vpi,atmh->vci,atmh->type);
+				tx_cells++;
+				target_->recv(p,h);
+				break;
+			}
+
+		}
+}
+
+/* here again, I haven't worried about incoming PVC or rxtps.  
+   I haven't the slightest idea where to find information re:
+   their significance. */
+
+void AtmConditioner::usage_parameter_control(Packet *p,Handler *h) {
+
+	Tcl &tcl = Tcl::instance();
+	double T;
+	bool conforms;
+        int type;
+
+	AtmQos *qos = classify(p);
+
+        if (qos == NULL) {
+		drops++;
+		drop(p);
+		return;
+         }
+
+        type = qos->get_rxtp()->traffic_class;
+	
+	
+	switch (type) {
+		
+	case CBR: 
+		{
+			int pcr = qos->get_rxtp()->pcr;
+			T = (double) (1.0/(double)pcr);
+			
+			conforms = gcra(T,qos->get_rxtp()->cdvt, qos);
+			upc_helper(conforms,p,h); 
+			
+		}
+		break;
+		
+	case rt_VBR:
+	case nrt_VBR:
+		{
+			double Ts = (double)(1.0/(double)(qos->get_rxtp()->scr));
+			T = (double) (1.0/(double)(qos->get_rxtp()->pcr));
+			int mbs = qos->get_rxtp()->mbs;
+			
+			double tau = (mbs - 1)*(Ts - T);
+			
+			conforms = gcra(Ts,tau,qos);
+			upc_helper(conforms,p,h);
+		}
+		break;
+	default: 
+		tcl.resultf("invalid service category %d\n",type);
+		break;
+		
+			
+	}
+
+
+}
+
+bool AtmConditioner::gcra(double T, double tau, AtmQos *qos) {
+
+
+	double tat = qos->get_rxtp()->tat;
+
+	/* the first cell on the connection */
+	if (tat == -1) {
+//		printf("GCRA::conforms\n");
+		qos->get_rxtp()->tat = Scheduler::instance().clock() + T;
+		return true;
+	}
+	
+	double temp = Scheduler::instance().clock();
+
+	/* conforming */
+	if (temp >= tat) {
+//		printf("GCRA::conforms\n");
+		qos->get_rxtp()->tat += T;
+		return true;
+	}
+
+	else if ((temp < tat) && (tat <= (temp+tau))) {
+//		printf("GCRA::conforms\n");
+		qos->get_rxtp()->tat += T;
+		return true;
+	}
+
+	else if (temp < (tat - tau))
+		return false;
+
+	return false;
+}
+		
+		
+		
+	
+/* iat stands for interarrival time */
+// void AtmConditioner::traffic_shaping(Packet *p, Handler *h, double iat) {
+
+//	update_tokens(iat);
+
+	/* actual shaping function */
+
+	/* if the bucketsize > 0 and buffer is not empty, 
+           the bucket must have been updated in this run of
+           traffic shaping function */
+
+//	if (bucketsize > 0) {
+		
+/*		if (buffer.size() > 0) {
+		
+			do {
+				bucketsize--;
+				printf("AtmConditioner: %s sending packet to target\n",name());
+				target_->recv(buffer.front(),h);
+			} while ((buffer.size() > 0) && (bucketsize > 0));
+		
+			} */
+		/* sufficient time to collect another token might
+                   have elapsed after the while loop */
+		
+/*		if (bucketsize > 0) {
+			printf("AtmConditioner: %s sending packet to target\n",name());
+			target_->recv(p,h);
+			bucketsize--;
+		} else {
+			if (buffer_limit >= buffer.size())
+				{
+					printf("AtmConditioner::dropping, time = %e\n", Scheduler::instance().clock());
+					drop(p);
+				}
+			else
+				buffer.push_back(p);
+		}
+		
+	}
+	
+	else {
+		
+		if (buffer_limit >= buffer.size()) {
+			printf("AtmConditioner::dropping packet, time = %e\n", Scheduler::instance().clock());
+			drop(p);
+		}
+		else
+			buffer.push_back(p);
+	}
+
+	} */
+	 
+/* connection admission control */
+bool AtmConditioner::cac(path pth) {
+
+	AtmTrafprm *txtp = pth.outgoing_pvc.get_txtp();
+
+	// transmit side parameter check
+	
+	Tcl &tcl = Tcl::instance();
+
+	switch (txtp->traffic_class) {
+
+	case CBR:
+		/* for now, I am just considering conditioning on
+                   the outgoing PVC and also only the transmit
+                   traffic descriptor information.  I will have
+                   to find out the significance of the rx traffic
+                   descriptor as well as the incoming pvc */
+
+		if ((txtp->pcr * CELLSIZE * BYTE) >= pvc_dbase->avail_rate()) {
+			return false;
+		}
+		else {
+			pvc_dbase->set_avail_rate((txtp->pcr) * CELLSIZE * BYTE);
+			return true;
+		}
+		
+		break;
+
+	case rt_VBR:
+
+
+		if ((CELLSIZE * BYTE *((1+A1)*txtp->scr)) >= pvc_dbase->avail_rate()) {
+
+			printf("AtmCond::cac, requested rate = %e,scr = %d\n",CELLSIZE*BYTE*((1+A1)*txtp->scr),txtp->scr);
+			return false;
+		}
+		else {
+			pvc_dbase->set_avail_rate( (txtp->scr) * CELLSIZE * BYTE);
+			return true;
+		}
+		break;
+
+	case nrt_VBR:
+
+		if ((txtp->scr * CELLSIZE * BYTE )>= pvc_dbase->avail_rate())
+			return false;
+		else {
+			pvc_dbase->set_avail_rate((txtp->scr) * CELLSIZE * BYTE);
+			return true;
+		}
+
+		break;
+
+	case ABR:
+	case GFR:
+
+		if ((txtp->mcr * CELLSIZE * BYTE) >= pvc_dbase->avail_rate())
+			return false;
+		else {
+			pvc_dbase->set_avail_rate((txtp->mcr) * CELLSIZE * BYTE);
+			return true;
+		}
+		break;
+
+	case UBR:
+		break;
+
+	default:
+		tcl.resultf("unknown ATM traffic class");
+	}
+	return true;
+}
+
+AtmQos *AtmConditioner::classify(Packet *p) {
+
+	hdr_atm *atmh = hdr_atm::access(p);
+
+	return pvc_dbase->incoming_qos_lookup(atmh->vpi,atmh->vci);
+}
+
+
+
+
+void AtmConditioner::upc_helper_old(bool conforms, Packet *p, Handler *h) 
+{
+	hdr_atm *atmh = hdr_atm::access(p);
+	Tcl &tcl = Tcl::instance();
+
+	int idx = find_bucket(p);
+
+	if (conforms && ((atmh->clp == 0) || (atmh->clp == 1))) 
+		{
+			
+			if (idx  < 0) {
+				tcl.resultf("AtmConditioner::traffic unprovisioned");
+				return;
+			}
+				
+
+			if (leakybucket[idx]->size() > 0) {
+				Packet *temp = leakybucket[idx]->first();
+				leakybucket[idx]->erase();
+				tx_cells++;
+				target_->recv(temp,h);
+			}
+			// traffic_shaping(leakybucket[idx]->first(),h,(double)1/bucketrate);
+
+		}
+	
+	else if (!conforms && (atmh->clp == 0)) {
+		atmh->clp = 1;
+	}
+	
+	else if (!conforms && (atmh->clp == 1)) {
+		//	printf("AtmConditioner :: ID %s dropping packet at %e\n",name(),Scheduler::instance().clock());
+		drops++;
+		drop(leakybucket[idx]->first());
+		leakybucket[idx]->erase();
+	}
+	
+}
+
+
+/* since NS is a single thread simulator, tokens into a bucket cannot
+   be generated parallely without being interrupted by other tasks.
+   Therefore, I use an approximation to the token generation concept.
+
+   I maintain a time variable that is basically the time at which the
+   previous token was generated.  The floor or integer value of
+   elapsed_time/token_bucket_rate gives the number of tokens that must
+   be input into the bucket. */
+
+ void AtmConditioner::update_tokens (double iat) {
+	
+	 double temp = Scheduler::instance().clock();
+	 double elapsed_time = temp - last_token_update_time;
+	 last_token_update_time = temp;
+	 
+	 bucketsize += (int)(elapsed_time/iat);
+ }
+
+
+ int AtmConditioner::find_bucket(Packet *p)
+	 {
+
+		 hdr_atm *atmh = hdr_atm::access(p);
+
+		 for (unsigned int i = 0; i < leakybucket.size(); i++)
+			 {
+				 int vp = (int)leakybucket[i]->vpi();
+				 int vc = (int)leakybucket[i]->vci();
+				 
+				 if ((vp == atmh->vpi) && (vc == atmh->vci))
+					 return i;
+			 }
+
+		 return -1;
+	 }
+				 
+ void AtmConditioner::store_cell(Packet *p)
+	 {
+
+		 int idx = find_bucket(p);
+		 hdr_atm *atmh = hdr_atm::access(p);
+
+		 if (idx > -1) {
+			 if (leakybucket[idx]->size() < bucketlimit)
+				 leakybucket[idx]->push_back(p);
+			 
+			 else {
+				 drops++;
+				 drop(p);
+			 }
+		 }
+		 else {
+			 VCBuffer *l = new VCBuffer(atmh->vpi,atmh->vci);
+			 leakybucket.push_back(l);
+			 leakybucket[leakybucket.size() - 1]->push_back(p);
+
+		 }
+		 
+		 return;
+	 }
+
+char *decode_type(int type)
+{
+	if (type == CBR)
+		return "CBR";
+	
+	else if (type == rt_VBR)
+		return "rt-VBR";
+
+	else if (type == nrt_VBR)
+		return "nrt-VBR";
+
+	else if (type == GFR)
+		return "GFR";
+
+	else if (type == ABR)
+		return "ABR";
+
+	else if (type == UBR)
+		return "UBR";
+
+	else
+		return "UNKNOWN";
+}
+
+// the policing for gfr is frame based and hence the calculations 
+// vary from normal gcra.
+
+void AtmConditioner::gfr_upc(Packet *p, Handler *h) {
+
+	bool clp  = gfr_clp(p);
+	bool gcra = f_gcra(p);
+	bool mfs  = gfr_mfs(p);
+
+	if (gcra && mfs && clp) {
+		tx_cells++;
+		target_->recv(p,h);
+	}
+
+	else {
+		drops++;
+		drop(p);
+	}
+
+	return;
+}
+
+
+// frame based gcra
+
+bool AtmConditioner::f_gcra(Packet *p) {
+
+	hdr_atm *atmh = hdr_atm::access(p);
+	
+	AtmQos *qos = classify(p);
+        AtmTrafprm *rxtp  = qos->get_rxtp();
+
+	double T = 1/(rxtp->mcr);
+	double BT = ((rxtp->mbs) - 1)*((1/rxtp->mcr) - (1/rxtp->pcr));
+	double L = BT + rxtp->cdvt;
+
+	printf("%e  %e    %e 0x%x\n",T,BT,L,atmh);
+
+
+	return gcra(T,BT+rxtp->cdvt,qos);
+}
+
+
+bool AtmConditioner::gfr_mfs(Packet *p) {
+
+	hdr_atm *atmh = hdr_atm::access(p);
+	AtmTrafprm *rxtp = classify(p)->get_rxtp();
+	int gfr_idx = find_gfr_cell_cnt(atmh->vpi, atmh->vci);
+	int gcnt = gfr_cells_per_vc[gcnt].gfr_cells;
+
+	if (( ((atmh->type%2) != 1) && (rxtp->mfs > gcnt)) || (atmh->type%2 == 1))
+		{
+			gfr_cells_per_vc[gfr_idx].gfr_cells++;
+			return true;
+		}
+
+	return false;
+}
+
+
+bool AtmConditioner::gfr_clp(Packet *p) {
+
+	hdr_atm *atmh = hdr_atm::access(p);
+
+	int idx = find_gfr_cell_cnt(atmh->vpi,atmh->vci);
+
+	// this is the first cell on the vc
+	if (idx == -1) {
+		gfr_info info = gfr_info(atmh->vpi, atmh->vci, atmh->clp);
+		gfr_cells_per_vc.push_back(info);
+	}
+
+
+	else {
+		if (atmh->clp == gfr_cells_per_vc[idx].clp)
+			return true;
+		return false;
+	}
+		
+	return false;
+}
+
+
+int AtmConditioner::find_gfr_cell_cnt(int vpi, int vci) {
+
+	for(int i=0; i < gfr_cells_per_vc.size() ; i++) {
+		int vp = gfr_cells_per_vc[i].vpi;
+		int vc = gfr_cells_per_vc[i].vci;
+
+		if ((vp == vpi) && (vc == vci))
+			return i;
+	}
+
+	return -1;
+}
+
+
+void AtmConditioner::upc_helper(bool conforms,Packet *p, Handler *h) {
+
+         int idx = find_bucket(p);
+         hdr_atm *atmh = hdr_atm::access(p);
+
+         printf("AtmConditioner::upc_helper, vpi/vci = %d/%d size = %d\n",
+                                        atmh->vpi,
+                                        atmh->vci,
+                                        leakybucket.size());
+
+         if (conforms) {
+                if (idx < 0) {
+                      tx_cells++;
+                      printf("AtmConditioner::sending packet to target\n");
+                      target_->recv(p,h);
+                }
+
+
+                else {
+                    Packet *c = (Packet *)leakybucket[idx]->first();
+                    leakybucket[idx]->erase();
+                    store_cell(p);
+                    tx_cells++;
+                    printf("AtmConditioner::sending packet to target\n");
+                    target_->recv(c,h);
+                }
+           }
+
+           else {
+
+                printf("AtmConditioner::storing packet\n");
+                store_cell(p);
+             }
+
+
+}
+
+
diff -urN ns-2.1b9/atm/atmconditioner.cc.old ns-allinone-2.1b9/ns-2.1b9/atm/atmconditioner.cc.old
--- ns-2.1b9/atm/atmconditioner.cc.old	Wed Dec 31 19:00:00 1969
+++ ns-allinone-2.1b9/ns-2.1b9/atm/atmconditioner.cc.old	Fri Jul 12 15:06:41 2002
@@ -0,0 +1,639 @@
+/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
+
+/*
+ * Copyright (c) 1999 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the MASH Research
+ *      Group at the University of California Berkeley.
+ * 4. Neither the name of the University nor of the Research Group may be
+ *    used to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * 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.
+ *
+ * @(#) $Header: /opt/src/mash/repository/vint/ns-2/atmnode.h,v 1.0 2000/06/19 17:35:09 sow Exp $
+ *
+ * Contributed by Sowmya Manjanatha, Dept. of Computer Science, UNH, August 2000 
+ */
+
+#include "atmconditioner.h"
+#include "atmpvc.h"
+#include "ip.h"
+
+static class AtmConditionerClass : public TclClass {
+public:
+	AtmConditionerClass() : TclClass("AtmConditioner") {}
+	TclObject* create(int, const char*const*) {
+		return (new AtmConditioner);
+		
+	}	
+} class_atmconditioner;
+
+
+AtmConditioner::AtmConditioner():qos(0),bucketsize(50000),available_bucket(50000),buffer_limit(50000) 
+{ 
+	bucketlimit = 2000;
+	
+	tx_cells = 0;
+	rx_cells = 0;
+	drops = 0;
+	non_cfm = 0;
+}
+
+
+int AtmConditioner::command(int argc, const char*const* argv) {
+
+
+	if (argc == 2) {
+	  if (strcmp (argv[1], "conditioner_statistics") == 0) {
+		  printf("   %8d             %12d               %5d     %5d     \n",rx_cells,tx_cells,drops,non_cfm);
+	  
+		  return TCL_OK;
+	  }
+	}
+		
+
+	if (argc == 3) {
+		
+		if (strcmp("set-profile",argv[1]) == 0) {
+			return TCL_OK;
+		}
+		
+		if (strcmp("add-pvc_dbase",argv[1]) == 0) {
+			pvc_dbase = (pvc_db *) TclObject::lookup(argv[2]);
+			return TCL_OK;
+		}
+		
+		if (strcmp("total_service_rate_", argv[1]) == 0) {
+			total_service_rate = atof(argv[2]);
+			available_service_rate = total_service_rate;
+			printf("AtmConditioner::cac, avail service rate = %e\n", available_service_rate);
+			
+			if(total_service_rate < 0)
+			  return TCL_ERROR;
+			return TCL_OK;
+		}
+	}
+	
+	return (Connector::command(argc,argv));
+}
+
+/* This is where the cell first enters into the ATM Network.
+   Well, this is because the traffic entering is conditioned
+   upfront given to the fact that the AtmConditioner is installed
+   between a link and a node. */
+
+
+void AtmConditioner::recv(Packet *p, Handler *h) {
+
+	int idx;
+
+  /* Here I follow a strict allocation procedure. 
+     If traffic is conforming, I allocate, else I drop */
+
+	hdr_atm *atmh = hdr_atm::access(p);
+
+        AtmQos *qos = classify(p);
+
+	rx_cells++;
+
+	if (qos == NULL) {
+		printf("AtmConditioner :: qos is NULL, dropping packet\n");
+		drops++;
+		drop(p);
+	}
+
+	
+	else
+		{
+			switch (qos->get_rxtp()->traffic_class) {
+				
+			case CBR:
+			case rt_VBR:
+			case nrt_VBR:
+		//		store_cell(p);
+				usage_parameter_control(p,h);   
+				
+				break;
+			case GFR:
+				gfr_upc(p,h);
+			case ABR:
+			case UBR:
+				// traffic_shaping(p,h,(double)1/bucketrate);
+
+				//				printf("AtmConditioner:: sending packet to target, vpi/vci = %d/%d, type = %d\n",atmh->vpi,atmh->vci,atmh->type);
+				tx_cells++;
+				target_->recv(p,h);
+				break;
+			}
+
+		}
+}
+
+/* here again, I haven't worried about incoming PVC or rxtps.  
+   I haven't the slightest idea where to find information re:
+   their significance. */
+
+void AtmConditioner::usage_parameter_control(Packet *p,Handler *h) {
+
+	Tcl &tcl = Tcl::instance();
+	double T;
+	bool conforms;
+        int type;
+
+	AtmQos *qos = classify(p);
+
+        if (qos == NULL) {
+		drops++;
+		drop(p);
+		return;
+         }
+
+        type = qos->get_rxtp()->traffic_class;
+	
+	
+	switch (type) {
+		
+	case CBR: 
+		{
+			int pcr = qos->get_rxtp()->pcr;
+			T = (double) (1.0/(double)pcr);
+			
+			conforms = gcra(T,qos->get_rxtp()->cdvt, qos);
+			upc_helper(conforms,p,h); 
+			
+		}
+		break;
+		
+	case rt_VBR:
+	case nrt_VBR:
+		{
+			double Ts = (double)(1.0/(double)(qos->get_rxtp()->scr));
+			T = (double) (1.0/(double)(qos->get_rxtp()->pcr));
+			double tau_s = qos->get_rxtp()->cdvt;
+			int mbs = qos->get_rxtp()->mbs;
+			
+			double tau = (mbs - 1)*(Ts - T);
+			conforms = gcra(Ts,(tau+tau_s),qos);
+			upc_helper(conforms,p,h);
+		}
+		break;
+	default: 
+		tcl.resultf("invalid service category %d\n",type);
+		break;
+		
+			
+	}
+
+
+}
+
+bool AtmConditioner::gcra(double T, double tau, AtmQos *qos) {
+
+
+	double tat = qos->get_rxtp()->tat;
+
+	/* the first cell on the connection */
+	if (tat == -1) {
+//		printf("GCRA::conforms\n");
+		qos->get_rxtp()->tat = Scheduler::instance().clock() + T;
+		return true;
+	}
+	
+	double temp = Scheduler::instance().clock();
+
+
+	/* conforming */
+	if (temp >= tat) {
+//		printf("GCRA::conforms\n");
+		qos->get_rxtp()->tat += T;
+		return true;
+	}
+
+	else if ((temp < tat) && (tat <= (temp+tau))) {
+//		printf("GCRA::conforms\n");
+		qos->get_rxtp()->tat += T;
+		return true;
+	}
+
+	else if (temp < (tat - tau)) {
+                non_cfm++;
+		return false;
+        }
+
+	return false;
+}
+		
+		
+		
+	
+/* iat stands for interarrival time */
+// void AtmConditioner::traffic_shaping(Packet *p, Handler *h, double iat) {
+
+//	update_tokens(iat);
+
+	/* actual shaping function */
+
+	/* if the bucketsize > 0 and buffer is not empty, 
+           the bucket must have been updated in this run of
+           traffic shaping function */
+
+//	if (bucketsize > 0) {
+		
+/*		if (buffer.size() > 0) {
+		
+			do {
+				bucketsize--;
+				printf("AtmConditioner: %s sending packet to target\n",name());
+				target_->recv(buffer.front(),h);
+			} while ((buffer.size() > 0) && (bucketsize > 0));
+		
+			} */
+		/* sufficient time to collect another token might
+                   have elapsed after the while loop */
+		
+/*		if (bucketsize > 0) {
+			printf("AtmConditioner: %s sending packet to target\n",name());
+			target_->recv(p,h);
+			bucketsize--;
+		} else {
+			if (buffer_limit >= buffer.size())
+				{
+					printf("AtmConditioner::dropping, time = %e\n", Scheduler::instance().clock());
+					drop(p);
+				}
+			else
+				buffer.push_back(p);
+		}
+		
+	}
+	
+	else {
+		
+		if (buffer_limit >= buffer.size()) {
+			printf("AtmConditioner::dropping packet, time = %e\n", Scheduler::instance().clock());
+			drop(p);
+		}
+		else
+			buffer.push_back(p);
+	}
+
+	} */
+	 
+/* connection admission control */
+bool AtmConditioner::cac(path pth) {
+
+	AtmTrafprm *txtp = pth.outgoing_pvc.get_txtp();
+
+	// transmit side parameter check
+	
+	Tcl &tcl = Tcl::instance();
+
+	switch (txtp->traffic_class) {
+
+	case CBR:
+		/* for now, I am just considering conditioning on
+                   the outgoing PVC and also only the transmit
+                   traffic descriptor information.  I will have
+                   to find out the significance of the rx traffic
+                   descriptor as well as the incoming pvc */
+
+		if ((txtp->pcr * CELLSIZE * BYTE) >= pvc_dbase->avail_rate()) {
+			return false;
+		}
+		else {
+			pvc_dbase->set_avail_rate((txtp->pcr) * CELLSIZE * BYTE);
+			return true;
+		}
+		
+		break;
+
+	case rt_VBR:
+
+
+		if ((CELLSIZE * BYTE *((1+A1)*txtp->scr)) >= pvc_dbase->avail_rate()) {
+
+			printf("AtmCond::cac, requested rate = %e,scr = %d\n",CELLSIZE*BYTE*((1+A1)*txtp->scr),txtp->scr);
+			return false;
+		}
+		else {
+			pvc_dbase->set_avail_rate( (txtp->scr) * CELLSIZE * BYTE);
+			return true;
+		}
+		break;
+
+	case nrt_VBR:
+
+		if ((txtp->scr * CELLSIZE * BYTE )>= pvc_dbase->avail_rate())
+			return false;
+		else {
+			pvc_dbase->set_avail_rate((txtp->scr) * CELLSIZE * BYTE);
+			return true;
+		}
+
+		break;
+
+	case ABR:
+	case GFR:
+
+		if ((txtp->mcr * CELLSIZE * BYTE) >= pvc_dbase->avail_rate())
+			return false;
+		else {
+			pvc_dbase->set_avail_rate((txtp->mcr) * CELLSIZE * BYTE);
+			return true;
+		}
+		break;
+
+	case UBR:
+		break;
+
+	default:
+		tcl.resultf("unknown ATM traffic class");
+	}
+	return true;
+}
+
+AtmQos *AtmConditioner::classify(Packet *p) {
+
+	hdr_atm *atmh = hdr_atm::access(p);
+
+	return pvc_dbase->incoming_qos_lookup(atmh->vpi,atmh->vci);
+}
+
+
+
+
+void AtmConditioner::upc_helper_old(bool conforms, Packet *p, Handler *h) 
+{
+	hdr_atm *atmh = hdr_atm::access(p);
+	Tcl &tcl = Tcl::instance();
+
+	int idx = find_bucket(p);
+
+	if (conforms && ((atmh->clp == 0) || (atmh->clp == 1))) 
+		{
+			
+			if (idx  < 0) {
+				tcl.resultf("AtmConditioner::traffic unprovisioned");
+				return;
+			}
+				
+
+			if (leakybucket[idx]->size() > 0) {
+				Packet *temp = leakybucket[idx]->first();
+				leakybucket[idx]->erase();
+				tx_cells++;
+				target_->recv(temp,h);
+			}
+			// traffic_shaping(leakybucket[idx]->first(),h,(double)1/bucketrate);
+
+		}
+	
+	else if (!conforms && (atmh->clp == 0)) {
+		atmh->clp = 1;
+	}
+	
+	else if (!conforms && (atmh->clp == 1)) {
+		//	printf("AtmConditioner :: ID %s dropping packet at %e\n",name(),Scheduler::instance().clock());
+		drops++;
+		drop(leakybucket[idx]->first());
+		leakybucket[idx]->erase();
+	}
+	
+}
+
+
+/* since NS is a single thread simulator, tokens into a bucket cannot
+   be generated parallely without being interrupted by other tasks.
+   Therefore, I use an approximation to the token generation concept.
+
+   I maintain a time variable that is basically the time at which the
+   previous token was generated.  The floor or integer value of
+   elapsed_time/token_bucket_rate gives the number of tokens that must
+   be input into the bucket. */
+
+ void AtmConditioner::update_tokens (double iat) {
+	
+	 double temp = Scheduler::instance().clock();
+	 double elapsed_time = temp - last_token_update_time;
+	 last_token_update_time = temp;
+	 
+	 bucketsize += (int)(elapsed_time/iat);
+ }
+
+
+ int AtmConditioner::find_bucket(Packet *p)
+	 {
+
+		 hdr_atm *atmh = hdr_atm::access(p);
+
+		 for (unsigned int i = 0; i < leakybucket.size(); i++)
+			 {
+				 int vp = (int)leakybucket[i]->vpi();
+				 int vc = (int)leakybucket[i]->vci();
+				 
+				 if ((vp == atmh->vpi) && (vc == atmh->vci))
+					 return i;
+			 }
+
+		 return -1;
+	 }
+				 
+ void AtmConditioner::store_cell(Packet *p)
+	 {
+
+		 int idx = find_bucket(p);
+		 hdr_atm *atmh = hdr_atm::access(p);
+
+		 if (idx > -1) {
+			 if (leakybucket[idx]->size() < bucketlimit)
+				 leakybucket[idx]->push_back(p);
+			 
+			 else {
+				 drops++;
+				 drop(p);
+			 }
+		 }
+		 else {
+			 VCBuffer *l = new VCBuffer(atmh->vpi,atmh->vci);
+			 leakybucket.push_back(l);
+			 leakybucket[leakybucket.size() - 1]->push_back(p);
+
+		 }
+		 
+		 return;
+	 }
+
+char *decode_type(int type)
+{
+	if (type == CBR)
+		return "CBR";
+	
+	else if (type == rt_VBR)
+		return "rt-VBR";
+
+	else if (type == nrt_VBR)
+		return "nrt-VBR";
+
+	else if (type == GFR)
+		return "GFR";
+
+	else if (type == ABR)
+		return "ABR";
+
+	else if (type == UBR)
+		return "UBR";
+
+	else
+		return "UNKNOWN";
+}
+
+// the policing for gfr is frame based and hence the calculations 
+// vary from normal gcra.
+
+void AtmConditioner::gfr_upc(Packet *p, Handler *h) {
+
+	bool clp  = gfr_clp(p);
+	bool gcra = f_gcra(p);
+	bool mfs  = gfr_mfs(p);
+
+	if (gcra && mfs && clp) {
+		tx_cells++;
+		target_->recv(p,h);
+	}
+
+	else {
+		drops++;
+		drop(p);
+	}
+
+	return;
+}
+
+
+// frame based gcra
+
+bool AtmConditioner::f_gcra(Packet *p) {
+
+	hdr_atm *atmh = hdr_atm::access(p);
+	
+	AtmQos *qos = classify(p);
+        AtmTrafprm *rxtp  = qos->get_rxtp();
+
+	double T = 1/(rxtp->mcr);
+	double BT = ((rxtp->mbs) - 1)*((1/rxtp->mcr) - (1/rxtp->pcr));
+	double L = BT + rxtp->cdvt;
+
+	printf("%e  %e    %e 0x%x\n",T,BT,L,atmh);
+
+
+	return gcra(T,BT+rxtp->cdvt,qos);
+}
+
+
+bool AtmConditioner::gfr_mfs(Packet *p) {
+
+	hdr_atm *atmh = hdr_atm::access(p);
+	AtmTrafprm *rxtp = classify(p)->get_rxtp();
+	int gfr_idx = find_gfr_cell_cnt(atmh->vpi, atmh->vci);
+	int gcnt = gfr_cells_per_vc[gcnt].gfr_cells;
+
+	if (( ((atmh->type%2) != 1) && (rxtp->mfs > gcnt)) || (atmh->type%2 == 1))
+		{
+			gfr_cells_per_vc[gfr_idx].gfr_cells++;
+			return true;
+		}
+
+	return false;
+}
+
+
+bool AtmConditioner::gfr_clp(Packet *p) {
+
+	hdr_atm *atmh = hdr_atm::access(p);
+
+	int idx = find_gfr_cell_cnt(atmh->vpi,atmh->vci);
+
+	// this is the first cell on the vc
+	if (idx == -1) {
+		gfr_info info = gfr_info(atmh->vpi, atmh->vci, atmh->clp);
+		gfr_cells_per_vc.push_back(info);
+	}
+
+
+	else {
+		if (atmh->clp == gfr_cells_per_vc[idx].clp)
+			return true;
+		return false;
+	}
+		
+	return false;
+}
+
+
+int AtmConditioner::find_gfr_cell_cnt(int vpi, int vci) {
+
+	for(int i=0; i < gfr_cells_per_vc.size() ; i++) {
+		int vp = gfr_cells_per_vc[i].vpi;
+		int vc = gfr_cells_per_vc[i].vci;
+
+		if ((vp == vpi) && (vc == vci))
+			return i;
+	}
+
+	return -1;
+}
+
+
+void AtmConditioner::upc_helper(bool conforms,Packet *p, Handler *h) {
+
+         int idx = find_bucket(p);
+         hdr_atm *atmh = hdr_atm::access(p);
+
+
+         if (conforms) {
+                if (idx < 0) {
+                      tx_cells++;
+                      target_->recv(p,h);
+                }
+
+
+                else {
+                    Packet *c = (Packet *)leakybucket[idx]->first();
+                    leakybucket[idx]->erase();
+                    store_cell(p);
+                    tx_cells++;
+                    target_->recv(c,h);
+                }
+           }
+
+           else {
+
+                store_cell(p);
+             }
+
+
+}
+
+
diff -urN ns-2.1b9/atm/atmconditioner.h ns-allinone-2.1b9/ns-2.1b9/atm/atmconditioner.h
--- ns-2.1b9/atm/atmconditioner.h	Wed Dec 31 19:00:00 1969
+++ ns-allinone-2.1b9/ns-2.1b9/atm/atmconditioner.h	Fri Jul 12 15:06:41 2002
@@ -0,0 +1,120 @@
+
+/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
+
+/*
+ * Copyright (c) 1999 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the MASH Research
+ *      Group at the University of California Berkeley.
+ * 4. Neither the name of the University nor of the Research Group may be
+ *    used to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * 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.
+ *
+ * @(#) $Header: /opt/src/mash/repository/vint/ns-2/atmnode.h,v 1.0 2000/08/09 20:43:00 sow Exp $
+ *
+ * Contributed by Sowmya Manjanatha, Dept. of Computer Science, UNH, August 2000
+ */
+
+#ifndef __atmconditioner_h__
+#define __atmconditioner_h__
+
+#include "connector.h"
+#include "packet.h"
+#include "atm.h"
+#include "atmqos.h"
+#include <vector>
+#include "leakybucket.h"
+
+typedef struct path path;
+class pvc_db;
+
+// connection parameter constants for CAC
+
+#define A1 0
+#define A2 0
+#define A3 0
+#define A4 0
+#define A5 0
+#define A6 0
+#define A7 0
+#define A8 0
+#define A9 200
+
+class AtmConditioner: public Connector {
+public:
+  AtmConditioner();
+  void recv(Packet *p, Handler *h);
+  bool cac(path,int);
+  
+protected:
+  int command(int argc, const char*const* argv);	
+  void usage_parameter_control(Packet *, Handler *);
+  bool gcra(double, double, AtmQos *);
+  void traffic_shaping(Packet *, Handler *,double);
+  AtmQos *classify(Packet *p);
+  void upc_helper(bool, Packet *, Handler *);
+  void upc_helper_old(bool, Packet *, Handler *);
+  void update_tokens(double);
+  int find_bucket(Packet *);
+  void store_cell(Packet *);
+  void gfr_upc(Packet *, Handler *);
+  bool f_gcra(Packet *);
+  bool gfr_mfs(Packet *);
+  bool gfr_clp(Packet *);
+  int find_gfr_cell_cnt(int,int);
+  
+private:
+  int qos;
+  int bucketsize;
+  double bucketrate;
+  int available_bucket;
+  pvc_db *pvc_dbase;
+  double total_service_rate;
+  double available_service_rate;
+  vector <Packet *> buffer;
+  unsigned int buffer_limit;
+  double last_token_update_time;
+  vector <VCBuffer *> leakybucket;
+  int bucketlimit;
+  vector <gfr_info> gfr_cells_per_vc;
+
+  //statistics
+
+  unsigned int rx_cells;
+  unsigned int tx_cells;
+  unsigned int drops;
+  unsigned int non_cfm;
+
+};
+
+char *decode_type(int);
+
+
+
+#endif
+
+
+
diff -urN ns-2.1b9/atm/atmpvc.cc ns-allinone-2.1b9/ns-2.1b9/atm/atmpvc.cc
--- ns-2.1b9/atm/atmpvc.cc	Wed Dec 31 19:00:00 1969
+++ ns-allinone-2.1b9/ns-2.1b9/atm/atmpvc.cc	Fri Jul 12 15:06:41 2002
@@ -0,0 +1,302 @@
+/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
+/*
+ * Copyright (c) 1999 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the MASH Research
+ *      Group at the University of California Berkeley.
+ * 4. Neither the name of the University nor of the Research Group may be
+ *    used to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * 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.
+ *
+ * @(#) $Header: /opt/simulators/ns/expt/ns-sow/atm/atmnode.h,v 1.0 2000/06/19 17:35:09 sow Exp $
+ *
+ * Contributed by Sowmya Manjanatha, Dept. of Computer Science, UNH, June 2000 
+ */
+
+#include "atmpvc.h"
+
+
+PVC::PVC(int vp, int vc, AtmTrafprm *rx, AtmTrafprm *tx) {
+	vpi = vp;
+	vci = vc;
+	qos = new AtmQos(rx,tx);
+
+}
+
+
+int PVC::set_args(int vp, int vc, AtmTrafprm *rx, AtmTrafprm *tx) {
+	vpi = vp;
+	vci = vc;
+	qos = new AtmQos(rx,tx);
+
+	return (TCL_OK);
+}
+
+
+static class pvc_dbClass : public TclClass {
+public:
+	pvc_dbClass() : TclClass("pvc_db") {}
+	TclObject* create(int, const char*const*) {
+		return (new pvc_db);
+		
+	}	
+} class_pvc_db;
+
+
+pvc_db::pvc_db() {
+	bind("linknum_",&(resource.num_links));
+
+        for (int i = 0 ; i < MAX_LINKS; i++) {
+	    resource.bw[i] = 0.0;
+      	    resource.dly[i] = 0.0;
+        }
+        resource.num_links = 0;
+}
+
+int pvc_db::command(int argc, const char*const* argv) {
+  Tcl& tcl = Tcl::instance();
+
+               
+  if (argc == 5) {
+
+          if (strcmp("add-resources",argv[1]) == 0) {
+
+                 double bw = atof(argv[2]);
+                 double dly = atof(argv[3]);
+                 int link = atoi(argv[4]);
+
+                 resource.bw[link] = bw;
+                 resource.dly[link] = dly;
+                 resource.num_links++;
+
+                 return TCL_OK;
+          }
+  }
+  if (argc == 12) {
+
+	  if (strcmp("add-pvc",argv[1]) == 0) {
+
+		  //incoming pvc
+		  int vpi = atoi(argv[2]);
+
+		  if(vpi < 0) {
+			  tcl.resultf("PVC DATABASE::invalid value %s",argv[2]);	
+			  return TCL_ERROR;
+		  }
+
+		  int vci = atoi(argv[3]);
+
+		  if(vci < 0) {
+			  tcl.resultf("PVC DATABASE::invalid value %s",argv[3]);	
+			  return TCL_ERROR;
+		  }
+
+
+		  AtmTrafprm *rxtp = (AtmTrafprm*)TclObject::lookup(argv[4]);
+
+		  if(rxtp == NULL) {
+			  tcl.resultf("PVC DATABASE::invalid value %s",argv[4]);	
+			  return TCL_ERROR;
+		  }
+
+		  
+		  AtmTrafprm *txtp = (AtmTrafprm*)TclObject::lookup(argv[5]);		  
+		  
+		  if(rxtp == NULL) {
+			  tcl.resultf("PVC DATABASE::invalid value %s",argv[5]);	
+			  return TCL_ERROR;
+		  }
+
+
+		  PVC p = PVC(vpi,vci,rxtp,txtp);
+
+
+		  if (strcmp(argv[6],"map") != 0) {
+			  tcl.resultf("PVC DATABASE::no outgoing interface to map to");	
+			  return TCL_ERROR;
+		  };
+
+		  path pth;
+		  pth.incoming_pvc = p;
+
+		  //outgoing pvc
+
+		  vpi = atoi(argv[7]);
+
+		  if(vpi < 0) {
+			  tcl.resultf("PVC DATABASE::invalid value %s",argv[7]);	
+			  return TCL_ERROR;
+		  }
+
+		  vci = atoi(argv[8]);
+
+		  if(vpi < 0) {
+			  tcl.resultf("PVC DATABASE::invalid value %s",argv[8]);	
+			  return TCL_ERROR;
+		  }
+
+		  rxtp = (AtmTrafprm*)TclObject::lookup(argv[9]);
+
+		  if(rxtp == NULL) {
+			  tcl.resultf("PVC DATABASE::invalid value %s",argv[9]);	
+			  return TCL_ERROR;
+		  }
+
+		  txtp = (AtmTrafprm*)TclObject::lookup(argv[10]);		  
+		  
+		  if(txtp == NULL) {
+			  tcl.resultf("PVC DATABASE::invalid value %s",argv[10]);	
+			  return TCL_ERROR;
+		  }
+
+		  p = PVC(vpi,vci,rxtp,txtp);
+
+		  pth.outgoing_pvc = p;
+
+                  int link_num = atoi(argv[11]);
+
+
+                   if((link_num < 0) || (link_num > MAX_LINKS)) {
+			  tcl.resultf("PVC DATABASE::invalid value %s",argv[11]);	
+			  return TCL_ERROR;
+		  }
+
+		  // building the table
+
+		  printf("ATMPVC::vpi/vci = %d/%d,scr = %d\n",vpi,vci,txtp->scr);
+		  if (!(conditioner->cac(pth,link_num))) {
+	                  tcl.resultf("PVC DATABASE::resource not available\n");
+			  return TCL_ERROR;
+	          }
+
+		  pvc_table.push_back(pth);
+		  return (TCL_OK);
+	  }
+  }
+
+  if (argc == 3) {
+	  if(strcmp("attach-conditioner",argv[1]) == 0) {
+		  conditioner = (AtmConditioner*)TclObject::lookup(argv[2]);
+		  return TCL_OK;
+	  }
+  }
+
+  return (TclObject::command(argc,argv));
+}
+
+
+PVC *pvc_db::get_outgoing_pvc(int vpi, int vci) {
+	
+	for(unsigned int i=0; i < pvc_table.size(); i++) {
+		int vp = pvc_table[i].incoming_pvc.get_vpi();
+		int vc = pvc_table[i].incoming_pvc.get_vci();
+		if((vp == vpi) && (vc == vci)) 
+			return &(pvc_table[i].outgoing_pvc);
+	} 
+	return (PVC*)NULL;
+}
+
+PVC *pvc_db::get_corresponding_outgoing_pvc(int vpi, int vci) {
+	
+	for(unsigned int i=0; i < pvc_table.size(); i++) {
+		int vp = pvc_table[i].outgoing_pvc.get_vpi();
+		int vc = pvc_table[i].outgoing_pvc.get_vci();
+		
+		if((vp == vpi) && (vc == vci))
+			return &(pvc_table[i].outgoing_pvc);
+	}
+	return (PVC*)NULL;
+}
+
+PVC *pvc_db::get_incoming_pvc(int vpi, int vci) {
+	
+	for(unsigned int i=0; i < pvc_table.size(); i++) {
+		int vp = pvc_table[i].incoming_pvc.get_vpi();
+		int vc = pvc_table[i].incoming_pvc.get_vci();
+		if((vp == vpi) && (vc == vci)) 
+			return &(pvc_table[i].incoming_pvc);
+	} 
+	return (PVC*)NULL;
+}
+
+
+
+AtmQos *pvc_db::incoming_qos_lookup(int vpi, int vci) {
+	
+	AtmQos *q;
+
+	for(unsigned int i=0; i < pvc_table.size(); i++) {
+		int vp = pvc_table[i].incoming_pvc.get_vpi();
+		int vc = pvc_table[i].incoming_pvc.get_vci();
+
+		if((vp == vpi) && (vc == vci)) {
+			q = pvc_table[i].incoming_pvc.get_qos();
+			return q;
+		}
+
+	}
+
+	return (AtmQos *)NULL;
+}
+
+AtmQos *pvc_db::outgoing_qos_lookup(int vpi, int vci) {
+	
+
+	for(unsigned int i=0; i < pvc_table.size(); i++) {
+		int vp = pvc_table[i].outgoing_pvc.get_vpi();
+		int vc = pvc_table[i].outgoing_pvc.get_vci();
+
+		if((vp == vpi) && (vc == vci))
+			return pvc_table[i].outgoing_pvc.get_qos();
+
+	}
+
+	return (AtmQos *)NULL;
+}
+
+path *pvc_db::get_corresponding_table_entry(int vpi, int vci) {
+
+	for(unsigned int i=0; i < pvc_table.size(); i++) {
+
+		int vp = pvc_table[i].outgoing_pvc.get_vpi();
+		int vc = pvc_table[i].outgoing_pvc.get_vci();
+
+		if((vpi == vp) && (vci == vc))
+			return (path *)(&(pvc_table[i]));
+	}
+
+	return (path *)NULL;
+}
+
+double pvc_db::get_total_input_rate() {
+
+	double sum = 0.0;
+
+	for (unsigned int i=0; i < pvc_table.size(); i++) 
+		sum += pvc_table[i].input_rate;
+
+	return sum;
+}
diff -urN ns-2.1b9/atm/atmpvc.h ns-allinone-2.1b9/ns-2.1b9/atm/atmpvc.h
--- ns-2.1b9/atm/atmpvc.h	Wed Dec 31 19:00:00 1969
+++ ns-allinone-2.1b9/ns-2.1b9/atm/atmpvc.h	Fri Jul 12 15:06:41 2002
@@ -0,0 +1,116 @@
+/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
+/*
+ * Copyright (c) 1999 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the MASH Research
+ *      Group at the University of California Berkeley.
+ * 4. Neither the name of the University nor of the Research Group may be
+ *    used to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * 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.
+ *
+ * @(#) $Header: /opt/simulators/ns/expt/ns-sow/atm/atmnode.h,v 1.0 2000/06/19 17:35:09 sow Exp $
+ *
+ * Contributed by Sowmya Manjanatha, Dept. of Computer Science, UNH, June 2000 
+ */
+
+#ifndef __atmpvc_h__
+#define __atmpvc_h__
+
+#include "atmqos.h"
+#include <vector>
+#include "atmconditioner.h"
+
+#define MAX_PVCS 4000
+#define MAX_LINKS 10
+
+class PVC : public TclObject {
+public:
+	PVC() { }
+	PVC(int, int,AtmTrafprm *rx, AtmTrafprm *tx);
+	int set_args(int, int, AtmTrafprm *rx, AtmTrafprm *tx);
+	int get_vpi(){ return vpi ;}
+	int get_vci(){ return vci ;}
+	AtmTrafprm *get_rxtp() { return qos->get_rxtp(); }
+	AtmTrafprm *get_txtp() { return qos->get_txtp(); }
+	AtmQos *get_qos() { return qos; }
+
+
+private:
+	int vpi;
+	int vci;
+	AtmQos *qos;
+
+};
+
+typedef struct path {
+	PVC incoming_pvc;
+	PVC outgoing_pvc;
+	double input_rate;
+	double prev_cell_arrival_time;
+} path;
+
+
+typedef struct Resource {
+	double bw[MAX_LINKS];
+	double dly[MAX_LINKS];
+	double num_links;
+} Resource;
+
+
+class pvc_db : public TclObject {
+public:
+	pvc_db();
+	PVC *get_outgoing_pvc(int, int);
+	PVC *get_incoming_pvc(int,int);
+	PVC *get_corresponding_outgoing_pvc(int,int);
+	AtmQos *incoming_qos_lookup(int,int);
+	AtmQos *outgoing_qos_lookup(int,int);
+	int size() { return pvc_table.size(); }
+	path *get_corresponding_table_entry(int,int);
+	double get_total_input_rate();
+	double avail_rate(int linknum) { return resource.bw[linknum];}
+	double line_dly(int linknum) { return resource.dly[linknum];}
+	void set_avail_rate(double rt,int linknum) { resource.bw[linknum] -= rt; }
+	
+	
+protected:
+	int command(int argc, const char*const* argv);
+
+private:
+	vector<path> pvc_table;
+	AtmConditioner* conditioner;
+	Resource resource;
+};
+	
+#endif
+
+
+
+
+
+
+
+
diff -urN ns-2.1b9/atm/atmqos.cc ns-allinone-2.1b9/ns-2.1b9/atm/atmqos.cc
--- ns-2.1b9/atm/atmqos.cc	Wed Dec 31 19:00:00 1969
+++ ns-allinone-2.1b9/ns-2.1b9/atm/atmqos.cc	Fri Jul 12 15:06:41 2002
@@ -0,0 +1,584 @@
+/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
+/*
+ * Copyright (c) 1999 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the MASH Research
+ *      Group at the University of California Berkeley.
+ * 4. Neither the name of the University nor of the Research Group may be
+ *    used to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * 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.
+ *
+ * @(#) $Header: /opt/src/mash/repository/vint/ns-2/atmnode.h,v 1.0 2000/06/19 17:35:09 sow Exp $
+ *
+ * Contributed by Sowmya Manjanatha, Dept. of Computer Science, UNH, June 2000 
+ */
+
+
+#include "atmqos.h"
+#include <ctype.h>
+
+static class AtmTrafprmClass : public TclClass {
+public:
+	AtmTrafprmClass() : TclClass("AtmTrafprm") {}
+	TclObject* create(int, const char*const*) {
+		return (new AtmTrafprm);
+		
+	}	
+} class_atmtrafprm;
+
+AtmTrafprm* AtmTrafprm::instance_;
+
+
+
+int AtmTrafprm::command(int argc, const char*const* argv) {
+	
+	Tcl& tcl = Tcl::instance();
+
+	if ((instance_ == 0) || (instance_ != this))
+		instance_ = this;
+
+	if (argc == 12) {
+
+		/* pcr, cdvt, peak_2_peak_cdv, max_ctd, clr are the required traffic
+                   and qos parameters for CBR service */
+
+		if( strcmp("set-cbr",argv[1]) == 0)
+			return set_cbr(argv,tcl);
+
+
+		if( strcmp("set-nrt-vbr",argv[1]) == 0) {
+			return set_nrt_vbr(argv,tcl);
+		}
+				
+	}
+
+	if (argc == 14) {
+
+		if( strcmp("set-gfr",argv[1]) == 0)
+			return set_gfr(argv,tcl);
+
+	}
+
+	if (argc == 16) {
+
+		/* pcr, cdvt, peak_2_peak_cdv, max_ctd, clr,scr and mbs are 
+		   the required traffic and qos parameters for CBR service */
+
+		if( strcmp("set-rt-vbr",argv[1]) == 0)
+			return set_rt_vbr(argv,tcl);
+				
+	}
+
+	if (argc == 6) {
+
+		if( strcmp("set-ubr",argv[1]) == 0)
+			return set_ubr(argv,tcl);		
+
+	}
+
+	if (argc == 10) {
+
+		if( strcmp("set-abr",argv[1]) == 0)
+			return set_abr(argv,tcl);		
+
+	}
+
+	return (TclObject::command(argc,argv));
+}
+	
+
+/* cbr traffic and qos parameters required for cac and upc */
+
+int AtmTrafprm::set_cbr(const char*const* argv,Tcl &tcl) {		
+
+	traffic_class = CBR;
+
+	if (strcmp(argv[2],"pcr") != 0) {
+		tcl.resultf("pcr value required for CBR service\n");
+		return TCL_ERROR;
+	}
+	
+	// store pcr value
+	
+	if ((pcr = atoi(argv[3])) < 0) {
+		tcl.resultf("invalid pcr value %s\n", argv[3]);
+		return TCL_ERROR;
+	}
+	
+	if (strcmp(argv[4], "cdvt") != 0) {
+		tcl.resultf("cdvt value required for CBR service\n");
+		return TCL_ERROR;
+	}
+	
+	// store cdvt
+	
+	if ((cdvt = atof(argv[5])) < 0) {
+		tcl.resultf("invalid cdvt value %s\n",argv[5]);
+		return TCL_ERROR;
+	}
+	     
+	if (strcmp("p2p-cdv",argv[6]) != 0) {
+		tcl.resultf("p2p-cdv value required for CBR service\n");
+		return TCL_ERROR;	
+	}
+	
+	if ((peak_to_peak_cdv = atof(argv[7])) < 0) {
+		tcl.resultf("invalid p2p-cdv value %s\n",argv[7]);
+		return TCL_ERROR;
+	}
+
+	if (strcmp("max-ctd", argv[8]) != 0) {
+		tcl.resultf("max-ctd value required for CBR service\n");
+		return TCL_ERROR;	
+	}
+
+	if((max_ctd = atof(argv[9])) < 0) {
+		tcl.resultf("invalid max_ctd value %s\n",argv[9]);
+		return TCL_ERROR;
+	}
+
+	if (strcmp("clr", argv[10]) != 0) {
+		tcl.resultf("clr value required for CBR service\n");
+		return TCL_ERROR;	
+	}
+
+	if((clr = atof(argv[11])) < 0) {
+		tcl.resultf("invalid clr value %s\n",argv[11]);
+		return TCL_ERROR;
+	}
+
+
+	return TCL_OK;
+}
+
+
+/* cbr traffic and qos parameters required for cac and upc */
+
+int AtmTrafprm::set_rt_vbr(const char*const* argv,Tcl &tcl) {		
+
+	traffic_class = rt_VBR;
+
+	if (strcmp(argv[2],"pcr") != 0) {
+		tcl.resultf("pcr value required for rt-VBR service\n");
+		return TCL_ERROR;
+	}
+	
+	// store pcr value
+	
+	if ((pcr = atoi(argv[3])) < 0) {
+		tcl.resultf("invalid pcr value %s\n", argv[3]);
+		return TCL_ERROR;
+	}
+	
+	if (strcmp(argv[4], "cdvt") != 0) {
+		tcl.resultf("cdvt value required for rt-VBR service\n");
+		return TCL_ERROR;
+	}
+	
+	// store cdvt
+	
+	if ((cdvt = atof(argv[5])) < 0) {
+		tcl.resultf("invalid cdvt value %s\n",argv[5]);
+		return TCL_ERROR;
+	}
+        else
+           printf("AtmQos::rt-vbr,cdvt = %f\n",cdvt);
+	     
+	if (strcmp("scr",argv[6]) != 0) {
+		tcl.resultf("scr value required for rt-VBR service\n");
+		return TCL_ERROR;	
+	}
+
+	// collect scr
+
+	if ((scr = atoi(argv[7])) < 0) {
+		tcl.resultf("invalid scr value %s\n",argv[5]);
+		return TCL_ERROR;
+	}
+	     
+	if (strcmp("mbs",argv[8]) != 0) {
+		tcl.resultf("mbs value required for rt-VBR service\n");
+		return TCL_ERROR;	
+	}
+
+	// collect mbs
+
+	if ((mbs = atoi(argv[9])) < 0) {
+		tcl.resultf("invalid mbs value %s\n",argv[9]);
+		return TCL_ERROR;
+	}
+        else
+           printf("AtmQos::rt-vbr, mbs = %d\n",mbs);
+	     
+	if (strcmp("p2p-cdv",argv[10]) != 0) {
+		tcl.resultf("p2p-cdv value required for rt-VBR service\n");
+		return TCL_ERROR;	
+	}
+	
+	if ((peak_to_peak_cdv = atof(argv[11])) < 0) {
+		tcl.resultf("invalid p2p-cdv value %s\n",argv[11]);
+		return TCL_ERROR;
+	}
+
+	if (strcmp("max-ctd", argv[12]) != 0) {
+		tcl.resultf("max-ctd value required for rt-VBR service\n");
+		return TCL_ERROR;	
+	}
+
+	if((max_ctd = atof(argv[13])) < 0) {
+		tcl.resultf("invalid max_ctd value %s\n",argv[13]);
+		return TCL_ERROR;
+	}
+
+	if (strcmp("clr", argv[14]) != 0) {
+		tcl.resultf("clr value required for rt-VBR service\n");
+		return TCL_ERROR;	
+	}
+
+	if((clr = atof(argv[15])) < 0) {
+		tcl.resultf("invalid clr value %s\n",argv[15]);
+		return TCL_ERROR;
+	}
+
+
+	return TCL_OK;
+}
+
+
+/* nrt_vbr traffic and qos parameters required for cac and upc */
+
+int AtmTrafprm::set_nrt_vbr(const char*const* argv,Tcl &tcl) {		
+
+	traffic_class = nrt_VBR;
+
+	if (strcmp(argv[2],"pcr") != 0) {
+		tcl.resultf("pcr value required for nrt-VBR service\n");
+		return TCL_ERROR;
+	}
+	
+	// store pcr value
+	
+	if ((pcr = atoi(argv[3])) < 0) {
+		tcl.resultf("invalid pcr value %s\n", argv[3]);
+		return TCL_ERROR;
+	}
+	
+	if (strcmp(argv[4], "cdvt") != 0) {
+		tcl.resultf("cdvt value required for nrt-VBR service\n");
+		return TCL_ERROR;
+	}
+	
+	// store cdvt
+	
+	if ((cdvt = atof(argv[5])) < 0) {
+		tcl.resultf("invalid cdvt value %s\n",argv[5]);
+		return TCL_ERROR;
+	}
+        else
+           printf("AtmQos::nrt-vbr,cdvt = %f\n",cdvt);
+	     
+	if (strcmp("scr",argv[6]) != 0) {
+		tcl.resultf("scr value required for nrt-VBR service\n");
+		return TCL_ERROR;	
+	}
+	
+	if ((scr = atoi(argv[7])) < 0) {
+		tcl.resultf("invalid scr value %s\n",argv[7]);
+		return TCL_ERROR;
+	}
+
+	else {
+	     if (scr >= pcr) {
+		tcl.resultf("invalid scr value %s\n",argv[7]);
+		return TCL_ERROR;
+             }
+	}
+
+
+	if (strcmp("mbs", argv[8]) != 0) {
+		tcl.resultf("mbs value required for nrt-VBR service\n");
+		return TCL_ERROR;	
+	}
+
+	if((mbs = atoi(argv[9])) < 0) {
+		tcl.resultf("invalid mbs value %s\n",argv[9]);
+		return TCL_ERROR;
+        }
+	else
+	   printf("AtmQos::nrt-vbr,mbs = %d\n",mbs);
+	
+
+	if (strcmp("clr", argv[10]) != 0) {
+		tcl.resultf("clr value required for nrt-VBR service\n");
+		return TCL_ERROR;	
+	}
+
+	if((clr = atof(argv[11])) < 0) {
+		tcl.resultf("invalid clr value %s\n",argv[11]);
+		return TCL_ERROR;
+	}
+
+
+	return TCL_OK;
+}
+
+
+/* ubr traffic and qos parameters required for cac and upc */
+
+int AtmTrafprm::set_ubr(const char*const* argv,Tcl &tcl) {		
+
+	traffic_class = UBR;
+
+	if (strcmp(argv[2],"pcr") != 0) {
+		tcl.resultf("pcr value required for nrt-VBR service\n");
+		return TCL_ERROR;
+	}
+	
+	// store pcr value
+	
+	if ((pcr = atoi(argv[3])) < 0) {
+		tcl.resultf("invalid pcr value %s\n", argv[3]);
+		return TCL_ERROR;
+	}
+	
+	if (strcmp(argv[4], "cdvt") != 0) {
+		tcl.resultf("cdvt value required for nrt-VBR service\n");
+		return TCL_ERROR;
+	}
+	
+	// store cdvt
+	
+	if ((cdvt = atof(argv[5])) < 0) {
+		tcl.resultf("invalid cdvt value %s\n",argv[5]);
+		return TCL_ERROR;
+	}
+	     
+	return TCL_OK;
+}
+
+
+
+/* gfr traffic and qos parameters required for cac and upc */
+
+int AtmTrafprm::set_gfr(const char*const* argv,Tcl &tcl) {		
+
+	traffic_class = GFR;
+
+	if (strcmp(argv[2],"pcr") != 0) {
+		tcl.resultf("pcr value required for rt-VBR service\n");
+		return TCL_ERROR;
+	}
+	
+	// store pcr value
+	
+	if ((pcr = atoi(argv[3])) < 0) {
+		tcl.resultf("invalid pcr value %s\n", argv[3]);
+		return TCL_ERROR;
+	}
+	
+	if (strcmp(argv[4], "cdvt") != 0) {
+		tcl.resultf("cdvt value required for rt-VBR service\n");
+		return TCL_ERROR;
+	}
+	
+	// store cdvt
+	
+	if ((cdvt = atof(argv[5])) < 0) {
+		tcl.resultf("invalid cdvt value %s\n",argv[5]);
+		return TCL_ERROR;
+	}
+	     
+	if (strcmp("mcr",argv[6]) != 0) {
+		tcl.resultf("mcr value required for GFR service\n");
+		return TCL_ERROR;	
+	}
+
+	// collect mcr
+
+	if ((mcr = atoi(argv[7])) < 0) {
+		tcl.resultf("invalid mcr value %s\n",argv[7]);
+		return TCL_ERROR;
+	}
+	     
+	if (strcmp("mbs",argv[8]) != 0) {
+		tcl.resultf("mbs value required for GFR service\n");
+		return TCL_ERROR;	
+	}
+
+	// collect mbs
+
+	if ((mbs = atoi(argv[9])) < 0) {
+		tcl.resultf("invalid mbs value %s\n",argv[9]);
+		return TCL_ERROR;
+	}
+	     
+	if (strcmp("mfs",argv[10]) != 0) {
+		tcl.resultf("mfs value required for GFR service\n");
+		return TCL_ERROR;	
+	}
+	
+	if ((mfs = atoi(argv[11])) < 0) {
+		tcl.resultf("invalid mfs value %s\n",argv[11]);
+		return TCL_ERROR;
+	}
+
+	if (strcmp("clr", argv[12]) != 0) {
+		tcl.resultf("clr value required for GFR service\n");
+		return TCL_ERROR;	
+	}
+
+	if((clr = atof(argv[13])) < 0) {
+		tcl.resultf("invalid clr value %s\n",argv[13]);
+		return TCL_ERROR;
+	}
+
+	return TCL_OK;
+}
+
+
+/* abr traffic and qos parameters required for cac and upc */
+
+int AtmTrafprm::set_abr(const char*const* argv,Tcl &tcl) {		
+
+	traffic_class = ABR;
+
+	if (strcmp(argv[2],"pcr") != 0) {
+		tcl.resultf("pcr value required for ABR service\n");
+		return TCL_ERROR;
+	}
+	
+	// store pcr value
+	
+	if ((pcr = atoi(argv[3])) < 0) {
+		tcl.resultf("invalid pcr value %s\n", argv[3]);
+		return TCL_ERROR;
+	}
+
+	acr = pcr;
+	
+	if (strcmp(argv[4], "cdvt") != 0) {
+		tcl.resultf("cdvt value required for ABR service\n");
+		return TCL_ERROR;
+	}
+	
+	// store cdvt
+	
+	if ((cdvt = atof(argv[5])) < 0) {
+		tcl.resultf("invalid cdvt value %s\n",argv[5]);
+		return TCL_ERROR;
+	}
+	     
+	if (strcmp("mcr",argv[6]) != 0) {
+		tcl.resultf("mcr value required for ABR service\n");
+		return TCL_ERROR;	
+	}
+
+	// collect mcr
+
+	if ((mcr = atoi(argv[7])) < 0) {
+		tcl.resultf("invalid mcr value %s\n",argv[7]);
+		return TCL_ERROR;
+	}
+	     
+
+	if (strcmp("clr", argv[8]) != 0) {
+		tcl.resultf("clr value required for ABR service\n");
+		return TCL_ERROR;	
+	}
+
+	if((clr = atof(argv[9])) < 0) {
+		tcl.resultf("invalid clr value %s\n",argv[9]);
+		return TCL_ERROR;
+	}
+
+	return TCL_OK;
+}
+
+
+
+void AtmTrafprm::initialize() {
+
+	traffic_class = NIL;
+	max_pcr = NIL;
+	min_pcr = NIL;
+	pcr = 0;
+	scr = 0;
+	mcr = 0;
+	mbs = 0;
+	mfs = 0;
+	cdvt = NIL;
+	clr = NIL;
+	peak_to_peak_cdv = NIL;
+	max_sdu = NIL;
+	max_ctd = NIL;
+	icr = NIL;
+	tbe = NIL;
+	frtt = NIL;
+	rif = 1/16;
+	rdf = 1/16;
+	nrm_pres = 32;
+	trm_pres = NIL;
+	adtf_pres = NIL;
+	cdf_pres = NIL;
+	nrm = 32;
+	trm = NIL;
+	cdf = NIL;
+	spare = NIL;
+	tat = NIL;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+AtmQos::AtmQos(AtmTrafprm *rx, AtmTrafprm *tx) {
+
+	rxtp = rx;
+	txtp = tx;
+}
+
+
+
+
+
+
+
+
+
diff -urN ns-2.1b9/atm/atmqos.h ns-allinone-2.1b9/ns-2.1b9/atm/atmqos.h
--- ns-2.1b9/atm/atmqos.h	Wed Dec 31 19:00:00 1969
+++ ns-allinone-2.1b9/ns-2.1b9/atm/atmqos.h	Fri Jul 12 15:06:41 2002
@@ -0,0 +1,128 @@
+/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
+
+/*
+ * Copyright (c) 1999 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the MASH Research
+ *      Group at the University of California Berkeley.
+ * 4. Neither the name of the University nor of the Research Group may be
+ *    used to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * 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.
+ *
+ * @(#) $Header: /opt/src/mash/repository/vint/ns-2/atmnode.h,v 1.0 2000/06/19 17:35:09 sow Exp $
+ *
+ * Contributed by Sowmya Manjanatha, Dept. of Computer Science, UNH, June 2000 
+ */
+
+#ifndef __atmqos_h__
+#define __atmqos_h__
+
+#include <tclcl.h>
+#include <stdlib.h>
+
+#define CBR 0
+#define rt_VBR 1
+#define nrt_VBR 2
+#define ABR 3
+#define UBR 4
+#define GFR 5
+#define NIL -1
+
+class AtmTrafprm : public TclObject {
+public:
+	AtmTrafprm() {initialize();}
+
+	/* the parameters below are allowed to be public so that they can 
+           be set at configuration time */
+
+        /* parameters generic to most service categories */
+
+	int             traffic_class;  /* traffic class (UBR, ...) */
+	int             max_pcr;        /* maximum PCR in cells per second */
+	int             pcr;            /* desired PCR in cells per second */
+	int             scr;            /* desired SCR in cells per second */
+	int             mbs;            /* maximum burst size in cells */
+	int             mfs;            /* maximum frame size in cells */
+	double          cdvt;           /* cell delay variation tolerance */
+	int             min_pcr;        /* minimum PCR in cells per second */
+	double          clr;            /* cell loss ratio */
+	double          peak_to_peak_cdv;        /* maximum CDV in microseconds */
+	int             max_sdu;        /* maximum SDU in bytes */
+	double          max_ctd;        /* maximum cell transfer delay */
+
+	/* extra params for ABR */
+	
+	int    mcr;            /* minimum cell rate in cells/sec */
+	int    icr;            /* Initial Cell Rate (24-bit) */
+	int    acr;            // Allowed Cell Rate
+	int    tbe;            /* Transient Buffer Exposure (24-bit) */
+	int    frtt;      /* Fixed Round Trip Time (24-bit) */
+	double    rif;       /* Rate Increment Factor */
+	double    rdf;       /* Rate Decrease Factor */
+	int    nrm_pres;      /* nrm present bit */
+	int    trm_pres;      /* rm present bit */
+	int    adtf_pres;      /* adtf present bit */
+	int    cdf_pres;      /* cdf present bit*/
+	int    nrm;      /* Max # of Cells for each forward RM cell (3-bit) */
+	int    trm;      /* Time between forward RM cells (3-bit) */
+	int    adtf;     /* ACR Decrease Time Factor (10-bit) */
+	int    cdf;      /* Cutoff Decrease Factor (3-bit) */
+	int    spare;      /* spare bits */
+	double tat;        /* future arrival time of a cell on  a connection */
+
+protected:
+	int command(int argc, const char*const* argv);
+	static AtmTrafprm* instance_;
+	int set_cbr(const char*const*,Tcl &);
+	int set_rt_vbr(const char*const*, Tcl &);
+	int set_nrt_vbr(const char*const*, Tcl &);
+	int set_ubr(const char*const*, Tcl &);
+	int set_abr(const char*const*, Tcl &);
+	int set_gfr(const char*const*, Tcl &);
+	void initialize();
+
+
+};
+
+class AtmQos {
+public:
+	AtmQos(){ }
+	AtmQos(AtmTrafprm *rx,  AtmTrafprm *tx);
+	AtmTrafprm *get_txtp() { return txtp; }
+	AtmTrafprm *get_rxtp() { return rxtp; }
+
+private:
+	AtmTrafprm *rxtp;
+	AtmTrafprm *txtp;
+};
+
+
+#endif
+
+
+
+
+
diff -urN ns-2.1b9/atm/atmqueue.h ns-allinone-2.1b9/ns-2.1b9/atm/atmqueue.h
--- ns-2.1b9/atm/atmqueue.h	Wed Dec 31 19:00:00 1969
+++ ns-allinone-2.1b9/ns-2.1b9/atm/atmqueue.h	Fri Jul 12 15:06:41 2002
@@ -0,0 +1,104 @@
+/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
+/*
+ * Copyright (c) 2000 Regents of the University of New Hampshire.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the MASH Research
+ *      Group at the University of California Berkeley.
+ * 4. Neither the name of the University nor of the Research Group may be
+ *    used to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * 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.
+ *
+ * @(#) $Header: /opt/src/mash/repository/vint/ns-2/atmnode.h,v 1.0 2000/07/20 14:50 sow Exp $
+ *
+ * Contributed by Sowmya Manjanatha, Dept. of Computer Science, UNH, July 2000 
+ */
+
+#ifndef __atmqueue_h__
+#define __atmqueue_h__
+
+#include "packet.h"
+#include <vector>
+
+#define CBR     0
+#define rt_VBR  1
+#define nrt_VBR 2
+#define ABR     3
+#define UBR     4
+#define GFR     5
+
+#define Q_DEF   200
+
+class AtmQueue {
+ public:
+	AtmQueue() : qlength(2000) { }
+	AtmQueue(int vp, int vc) : qlength(Q_DEF),vpi(vp),vci(vc),q_in(0),q_drop(0) { }
+	Packet *deque(int clp) {
+		if (queue[clp].size() > 0) {
+			Packet *temp = (Packet *)(*(queue[clp].begin()));
+			queue[clp].erase(queue[clp].begin());
+			return temp;
+		}
+
+		return (Packet*)NULL;
+	}
+	int get_vpi() { return vpi;}
+	int get_vci() { return vci;}
+        void set_qlength(int qlen) { qlength = qlen; }
+	void set_vpi(int vp) { vpi = vp; }
+	void set_vci(int vc) { vci = vc; }
+	vector<Packet *> get_queue_clp0() { return queue[0]; }
+	vector<Packet *> get_queue_clp1() { return queue[1]; }
+		
+	bool enque(Packet *p,int clp) { 
+		q_in++;
+		if ((int)queue[clp].size() <= qlength) {
+			queue[clp].push_back(p);
+			return true;
+		}
+		// printf("AtmQueue::enque, qlength exceeded\n");
+		q_drop++;
+		return false;
+	}
+
+	unsigned int qin_cnt () { return q_in; }
+	unsigned int qdrop_cnt () { return q_drop; }
+		
+  
+private:
+	vector<Packet *> queue[2];       /* the six queues are representative of six
+                                            service categories in atm */
+	int qlength;
+	int vpi;
+	int vci;
+	unsigned int q_in;
+	unsigned int q_drop;
+	
+};
+
+#endif
+
+
+
diff -urN ns-2.1b9/atm/atmscheduler.cc ns-allinone-2.1b9/ns-2.1b9/atm/atmscheduler.cc
--- ns-2.1b9/atm/atmscheduler.cc	Wed Dec 31 19:00:00 1969
+++ ns-allinone-2.1b9/ns-2.1b9/atm/atmscheduler.cc	Fri Jul 12 15:06:41 2002
@@ -0,0 +1,695 @@
+/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
+/*
+ * Copyright (c) 2000 Regents of the University of New Hampshire.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the MASH Research
+ *      Group at the University of California Berkeley.
+ * 4. Neither the name of the University nor of the Research Group may be
+ *    used to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * 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.
+ *
+ * @(#) $Header: /opt/src/mash/repository/vint/ns-2/atmscheduler.h,v 1.0 2000/07/22 22:46 sow Exp $
+ *
+ * Contributed by Sowmya Manjanatha, Dept. of Computer Science, UNH, July 2000 
+ */
+
+#include "atmscheduler.h"
+
+static class AtmSchedulerClass : public TclClass {
+public:
+	AtmSchedulerClass() : TclClass("AtmScheduler") {}
+	TclObject* create(int, const char*const*) {
+		return (new AtmScheduler);
+		
+	}	
+} class_atmscheduler;
+
+
+inline void AtmSchedulerHandler::handle(Event *e)
+{
+	scheduler->resume();
+}
+
+AtmScheduler::AtmScheduler() : Connector(),handler(this),idle_(true) { 
+
+	last_served_category = -1;
+	
+	for (int i=0; i < NUM_CATEGORIES; i++)
+		last_served_queue_in_category[i] = -1;
+
+	for (int i=0; i < MAX_Q; i++)
+		cells_per_round[i] = -1;
+
+	bind ("bytes-per-round",&bytes_per_round);
+
+	tx_cells = 0;
+	rx_cells = 0;
+	drops = 0;
+	undequeued  = 0;
+        
+        for (int i = 0; i < NUM_CATEGORIES; i++) {
+            for (int j=0; j < MAX_Q; j++) {
+                qWeight[i][j] = 1;
+                wrrTemp[i][j] = 0;
+            }
+        }
+
+        last_served_q = -1;
+}
+
+
+void AtmScheduler::recv(Packet *p, Handler *h) {
+
+	hdr_atm *atmh = hdr_atm::access(p);
+
+	update_total_input_rate(atmh->vpi,atmh->vci);
+
+	rx_cells++;
+
+
+	bool enqueued = enque(p);
+
+	if (enqueued == false) 
+		{
+			drops++;
+			drop(p);
+		}
+	
+	
+	if (idle_ && enqueued) {
+		idle_ = false;
+		assign_service_sizes_per_category();
+		resume();
+	}  
+	
+
+}
+
+void AtmScheduler::resume() {
+
+	Packet *c;
+
+
+	c = deque();
+
+	if (c == NULL) {
+		undequeued++;
+		// printf("AtmScheduler::atm_queue length is zero\n");
+		idle_ = true;
+		return;
+	}
+
+	tx_cells++;
+	target_->recv(c,&handler);  
+	
+	
+}
+
+int AtmScheduler::command(int argc, const char*const* argv) {
+
+	unsigned int temp = 0;
+	
+	if (argc == 2) {
+	  if (strcmp (argv[1], "scheduler_statistics") == 0) {
+		  for (int i=0; i < (int)per_vc_q[UBR].size() ; i++) 
+			  temp += per_vc_q[UBR][i].qin_cnt();
+
+		  printf("   %8d     %12d       %7d   %5d   %5d   \n",rx_cells,tx_cells,drops,temp,undequeued);
+	  
+		  return TCL_OK;
+	  }
+	}
+	
+
+
+	if (argc == 3) {
+		// assigning queue lengths
+		if (strcmp("queue-length-cbr",argv[1]) == 0) {
+			cbr_qlength = atoi(argv[2]);
+
+			if (cbr_qlength < 0)
+				return TCL_ERROR;
+			return TCL_OK;
+		}
+
+		if (strcmp("queue-length-rt-vbr",argv[1]) == 0) {
+			rt_vbr_qlength = atoi(argv[2]);
+
+			if (rt_vbr_qlength < 0)
+				return TCL_ERROR;
+			return TCL_OK;
+		}
+
+		if (strcmp("queue-length-nrt-vbr",argv[1]) == 0) {
+			nrt_vbr_qlength = atoi(argv[2]);
+
+			if (nrt_vbr_qlength < 0)
+				return TCL_ERROR;
+			return TCL_OK;
+		}
+
+		if (strcmp("queue-length-abr",argv[1]) == 0) {
+			abr_qlength = atoi(argv[2]);
+
+			if (abr_qlength < 0)
+				return TCL_ERROR;
+			return TCL_OK;
+		}
+
+		if (strcmp("queue-length-ubr",argv[1]) == 0) {
+			ubr_qlength = atoi(argv[2]);
+
+			if (ubr_qlength < 0)
+				return TCL_ERROR;
+			return TCL_OK;
+		}
+
+		if (strcmp("queue-length-gfr",argv[1]) == 0) {
+			gfr_qlength = atoi(argv[2]);
+
+			if (gfr_qlength < 0)
+				return TCL_ERROR;
+			return TCL_OK;
+		}
+
+		//assigning queue weights
+		if (strcmp("queue-weight-cbr",argv[1]) == 0) {
+			cbr_qweight = atof(argv[2]);
+
+			if (cbr_qlength < 0.0)
+				return TCL_ERROR;
+			return TCL_OK;
+		}
+
+		if (strcmp("queue-weight-rt-vbr",argv[1]) == 0) {
+			rt_vbr_qweight = atof(argv[2]);
+
+			if (rt_vbr_qweight < 0.0)
+				return TCL_ERROR;
+			return TCL_OK;
+		}
+
+		if (strcmp("queue-weight-nrt-vbr",argv[1]) == 0) {
+			nrt_vbr_qweight = atof(argv[2]);
+
+			if (nrt_vbr_qweight < 0.0)
+				return TCL_ERROR;
+			return TCL_OK;
+		}
+
+		if (strcmp("queue-weight-abr",argv[1]) == 0) {
+			abr_qweight = atof(argv[2]);
+
+			if (abr_qweight < 0.0)
+				return TCL_ERROR;
+			return TCL_OK;
+		}
+
+		if (strcmp("queue-weight-ubr",argv[1]) == 0) {
+			ubr_qweight = atof(argv[2]);
+
+			if (ubr_qweight < 0.0)
+				return TCL_ERROR;
+			return TCL_OK;
+		}
+
+		if (strcmp("queue-weight-gfr",argv[1]) == 0) {
+			gfr_qweight = atof(argv[2]);
+
+			if (gfr_qweight < 0.0)
+				return TCL_ERROR;
+			return TCL_OK;
+		}
+
+		if (strcmp("attach-pvc_dbase",argv[1]) == 0) {
+			pvc_dbase = (pvc_db *) TclObject::lookup(argv[2]);
+			return TCL_OK;
+		}
+	}
+        if (argc == 5) {
+                if (strcmp("set-qlength",argv[1]) == 0) {
+                        printf("set-qlength\n");
+                        return set_qlength(argv);
+                }
+                if (strcmp("set-qweight",argv[1]) == 0) {
+                        printf("set-qweight\n");
+                        return set_qweight(argv);
+                }
+        }
+             
+
+	return (Connector::command(argc,argv));
+}
+
+
+int AtmScheduler::set_qlength(const char*const* argv) {
+
+    int qnum = atoi(argv[3]);
+    int qlen = atoi(argv[4]);
+
+    printf("qlength  = %d,qnum = %d\n",qlen,qnum);
+
+    for (int i = 0; i < NUM_CATEGORIES ; i++) {
+          if (strcmp(argv[2], qosT[i]) == 0) {
+                qlen_[i][qnum] = qlen;
+                return TCL_OK;
+          }
+    }
+    return TCL_ERROR;
+}
+
+
+int AtmScheduler::set_qweight(const char*const* argv) {
+
+    int qnum = atoi(argv[3]);
+    int qwt = atoi(argv[4]);
+
+    printf("set qwt. qweight  = %d,qnum = %d\n",qwt,qnum);
+
+    for (int i = 0; i < NUM_CATEGORIES ; i++) {
+          if (strcmp(argv[2], qosT[i]) == 0) {
+                qWeight[i][qnum] = qwt;
+                return TCL_OK;
+          }
+    }
+    return TCL_ERROR;
+}
+
+void AtmScheduler::reset() {
+
+}
+
+
+//finds the per-vc-queue given vpi and vci values
+ int AtmScheduler::pvc_found(int vp, int vc,int type) {
+	
+	 for (unsigned int i=0; i < per_vc_q[type].size(); i++) {
+		 if ((vp == per_vc_q[type][i].get_vpi()) && (vc == per_vc_q[type][i].get_vci()))
+			 return (int)i;
+	 }
+	 
+	 return -1;
+ }
+ 
+ bool AtmScheduler::enque(Packet *p) {
+	 hdr_atm *atmh = hdr_atm::access(p);
+	 AtmTrafprm *txtp;
+
+	 PVC *pvc = pvc_dbase->get_corresponding_outgoing_pvc(atmh->vpi,atmh->vci);
+
+
+	 if (pvc != NULL)
+		 txtp = pvc->get_txtp();
+	 
+	 else {
+		 printf("AtmScheduler::packet vpi/vci = %d/%d\n",atmh->vpi,atmh->vci);
+
+		 printf("AtmScheduler::enque, PVC NOT found\n");
+		 return false;
+	 }
+	 int i;
+	 
+	 if ((i=pvc_found(atmh->vpi,atmh->vci,txtp->traffic_class)) > -1) {
+		 if (atmh->clp == 0)
+			 return per_vc_q[txtp->traffic_class][i].enque(p,0);
+		 else 
+			 return per_vc_q[txtp->traffic_class][i].enque(p,1);
+	 }
+	 
+	 else {
+		 AtmQueue temp_q(atmh->vpi,atmh->vci);
+                 int cl = txtp->traffic_class;
+                 temp_q.set_qlength(qlen_[cl][per_vc_q[cl].size()]);
+                 printf("AtmScheduler:: cl = %d, q = %d,size = %d\n",cl,per_vc_q[cl].size(),qlen_[cl][per_vc_q[cl].size()]);
+		 per_vc_q[txtp->traffic_class].push_back(temp_q);
+		 i = per_vc_q[txtp->traffic_class].size() - 1;
+		 if (atmh->clp == 0)
+			 return per_vc_q[txtp->traffic_class][i].enque(p,0);
+		 else 
+			 return per_vc_q[txtp->traffic_class][i].enque(p,1);
+	 } 
+ }
+ 
+ 
+ void AtmScheduler::assign_service_sizes_per_category () {
+	 
+	 double b = (double)bytes_per_round;
+	 double c = (double)CELLSIZE;
+
+	 cells_per_category[CBR]     = (int)((b * cbr_qweight)/c);
+	 cells_per_category[rt_VBR]  = (int)((b * rt_vbr_qweight)/c);
+	 cells_per_category[nrt_VBR] = (int)((b * nrt_vbr_qweight)/c);
+	 cells_per_category[ABR]     = (int)((b * abr_qweight)/c);
+	 cells_per_category[UBR]     = (int)((b * ubr_qweight)/c);
+	 cells_per_category[GFR]     = (int)((b * gfr_qweight)/c);
+ }
+ 
+
+void AtmScheduler::update_total_input_rate(int vp, int vc) {
+
+	path *entry = pvc_dbase->get_corresponding_table_entry(vp,vc);
+	double t =  Scheduler::instance().clock();
+
+	if (entry != NULL) {
+		double curr_rate = 1/(t - entry->prev_cell_arrival_time);
+		entry->input_rate = (entry->input_rate + curr_rate)/2;
+		total_input_rate = pvc_dbase->get_total_input_rate();
+	}
+
+}
+	
+Packet *AtmScheduler::deque_old() {
+	
+	Packet *p;
+	int q_trav=0;
+	
+	
+	int curr_ctgry = last_served_category+1;
+	int curr_q     = last_served_queue_in_category[curr_ctgry]+1;
+	int ctgries    = NUM_CATEGORIES;
+	int ctgry_trav=0;
+	
+	
+	int i = curr_ctgry;
+	while (i < ctgries)
+		{
+			ctgry_trav++;
+			p = per_vc_queuing(curr_q,per_vc_q[i].size(),i,q_trav);
+			
+			if(p)
+				{
+					last_served_category=i;
+					return p;
+				}
+
+			else if((!p) && (q_trav < (int)per_vc_q[i].size())) 
+				{
+				if(per_vc_queuing(0,curr_q,i,q_trav) != NULL)
+					{
+						last_served_category = i;
+						return p;
+					}
+				}
+
+			if ((i==(ctgries-1)) && (ctgry_trav < ctgries))
+				{
+					i=-1;
+					ctgries=curr_ctgry;
+				}
+
+			i++;
+			
+		}
+	
+	idle_ = true;
+	return (Packet *)NULL;
+}
+
+/* Description :  per_vc_queueing traverses the list of queues w.r.t the category input
+                  and finds a packet if available on a fifo basis */
+ 
+Packet *AtmScheduler::per_vc_queuing(int start, int end, int ctgry, int &q_trvsed)
+{
+	Packet *p;
+
+	for(int i=start; i < end; i++) 
+		{
+			for(int clp=0; clp < 2; clp++)
+				{
+					q_trvsed++;
+					if((p=per_vc_q[ctgry][i].deque(clp)) != NULL) {
+							last_served_queue_in_category[ctgry] = i;
+							return p;
+					}
+				}  
+					    
+		}
+
+	return (Packet *)NULL;
+
+}
+
+
+Packet *AtmScheduler::deque() {
+
+	
+//         return priority_scheduler();
+	 return wrr_scheduler();
+}
+	
+
+
+/* This is a simple priority scheduler, this method may be used both for per_vc_q scheduling and
+   per_category scheduling where CBR gets the highest priority and UBR gets the least */
+
+Packet *AtmScheduler::priority_scheduler() {
+	
+	Packet *p;
+
+	for (int i=0; i < NUM_CATEGORIES ; i++)
+		if((p=pri_vc_scheduler(i)) != NULL)
+			return p;
+
+	return (Packet*)NULL;
+}
+
+Packet *AtmScheduler::pri_vc_scheduler(int ctgry) {
+	
+	Packet *p;
+
+	for (int i=0 ; i < (int)per_vc_q[ctgry].size() ; i++) {
+
+		for (int clp=0; clp < 2; clp++)
+			if ((p=per_vc_q[ctgry][i].deque(clp)) != NULL)
+				return p;
+	}
+
+	return (Packet *)NULL;
+}
+	
+/* ********************************************************* */
+/*  This is a rate pacing scheduler.  The rate pacing happens 
+    according to the weights for each PVC which further depends
+    on individual parameters such as PCR for CBR, SCR for VBR
+    and MCR for ABR */
+/* ********************************************************* */
+	
+Packet *AtmScheduler::WRR_vc_scheduler(int ctgry) {
+
+	Packet *p;
+
+        int i = 0;
+      
+        /* *************************** */
+        // to avoid floation point errors
+        /* *************************** */
+
+        if (per_vc_q[ctgry].size() == 0)
+             return (Packet *)NULL;
+
+        if(wrrTemp[ctgry][last_served_q] <= 0) {
+             last_served_q = (last_served_q + 1) % per_vc_q[ctgry].size();
+	     wrrTemp[ctgry][last_served_q] = qWeight[ctgry][last_served_q] - 1;
+        } else {
+             wrrTemp[ctgry][last_served_q] = wrrTemp[ctgry][last_served_q] - 1;
+        }
+
+        while (i < (int)per_vc_q[ctgry].size()) {
+                
+             for (int clp = 0; clp < 2; clp++) {
+                 if((p=per_vc_q[ctgry][last_served_q].deque(clp)) != NULL) {
+                     return p;
+                }
+              }
+
+              wrrTemp[ctgry][last_served_q] = 0;
+              last_served_q = (last_served_q + 1) % per_vc_q[ctgry].size();
+              wrrTemp[ctgry][last_served_q] = qWeight[ctgry][last_served_q] - 1;
+              i++;
+
+        }
+        
+        return (Packet *)NULL;
+}
+
+
+Packet *AtmScheduler::wrr_scheduler() {
+	
+	Packet *p;
+
+	for (int i=0; i < (NUM_CATEGORIES-1) ; i++)
+		if((p=WRR_vc_scheduler(i)) != NULL)
+			return p;
+
+        /* ************************************ */
+        /* GFR gets the least priority          */
+        /* ************************************ */
+
+        if ((p=wrr_vc_scheduler(NUM_CATEGORIES-1)) != NULL)
+               return p;
+
+        return (Packet *)NULL;
+}
+
+
+Packet *AtmScheduler::wrr_vc_scheduler(int ctgry) {
+	
+	Packet *p;
+
+        int last = last_served_q;
+        int i = 0;
+
+
+        while (i < (int)per_vc_q[ctgry].size()) {
+
+              last = (last + 1) % per_vc_q[ctgry].size();
+                
+              for (int clp = 0; clp < 2; clp++) {
+                 if((p=per_vc_q[ctgry][last].deque(clp)) != NULL) {
+                      last_served_q = last;
+                      return p;
+                 }
+              }
+
+              i++;
+
+        }
+        
+        return (Packet *)NULL;
+}
+
+
+
+void AtmScheduler::cells_per_q(int ctgry) {
+
+         for (int i = 0; i < (int)per_vc_q[ctgry].size(); i++) 
+             cells_per_round[i] = CELLS_PER_ROUND;
+}
+
+             
+/* ********************************************************* */
+/*  GCRA algorithm used to decide on the rate pacing scheme
+    mentioned in the WRR_vc_scheduler
+    and MCR for ABR */
+/* ********************************************************* */
+
+
+bool AtmScheduler::gcra_helper(Packet *p,int qnum) {
+
+	Tcl &tcl = Tcl::instance();
+	double T;
+	bool conforms;
+        int type;
+        hdr_atm *atmh = hdr_atm::access(p);
+
+	AtmQos *qos = pvc_dbase->outgoing_qos_lookup(atmh->vpi,atmh->vci);
+
+        if (qos == NULL) 
+           return false;
+
+        type = qos->get_rxtp()->traffic_class;
+	
+	switch (type) {
+		
+	case CBR: 
+		{
+			int pcr = qos->get_rxtp()->pcr;
+			T = (double) (1.0/(double)pcr);
+			
+			conforms = gcra(T,qos->get_rxtp()->cdvt, type,qnum);
+                        return conforms;
+			
+		}
+		break;
+		
+	case rt_VBR:
+	case nrt_VBR:
+		{
+			double Ts = (double)(1.0/(double)(qos->get_rxtp()->scr));
+			T = (double) (1.0/(double)(qos->get_rxtp()->pcr));
+			double tau_s = qos->get_rxtp()->cdvt;
+			int mbs = qos->get_rxtp()->mbs;
+			
+			double tau = (mbs - 1)*(Ts - T);
+			conforms = gcra(Ts,(tau+tau_s),type,qnum);
+                        return conforms;
+		}
+		break;
+	case ABR: 
+		{
+			int mcr = qos->get_rxtp()->mcr;
+			T = (double) (1.0/(double)mcr);
+			conforms = gcra(T,qos->get_rxtp()->cdvt,type,qnum );
+                        return conforms;
+		}
+		break;
+	default: 
+		tcl.resultf("invalid service category %d\n",type);
+		break;
+		
+			
+	}
+return false;
+
+}
+
+/* ********************************************************* */
+/*  GCRA algorithm used to decide on the rate pacing scheme
+    mentioned in the WRR_vc_scheduler
+    and MCR for ABR */
+/* ********************************************************* */
+
+bool AtmScheduler::gcra(double T, double tau, int c, int q) {
+
+	double tat = tat_[c][q];
+
+	/* the first cell on the connection */
+	if (tat == -1) {
+		tat_[c][q] = Scheduler::instance().clock() + T;
+		return true;
+	}
+	
+	double temp = Scheduler::instance().clock();
+
+
+	/* conforming */
+	if (temp >= tat) {
+		tat_[c][q] += T;
+		return true;
+	}
+
+	else if ((temp < tat) && (tat <= (temp+tau))) {
+		tat_[c][q] = temp+T;
+		return true;
+	}
+
+	else if (temp < (tat - tau)) {
+                //non_cfm++;
+		return false;
+        }
+
+	return false;
+}
diff -urN ns-2.1b9/atm/atmscheduler.cc.0326 ns-allinone-2.1b9/ns-2.1b9/atm/atmscheduler.cc.0326
--- ns-2.1b9/atm/atmscheduler.cc.0326	Wed Dec 31 19:00:00 1969
+++ ns-allinone-2.1b9/ns-2.1b9/atm/atmscheduler.cc.0326	Fri Jul 12 15:06:41 2002
@@ -0,0 +1,446 @@
+/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
+/*
+ * Copyright (c) 2000 Regents of the University of New Hampshire.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the MASH Research
+ *      Group at the University of California Berkeley.
+ * 4. Neither the name of the University nor of the Research Group may be
+ *    used to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * 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.
+ *
+ * @(#) $Header: /opt/src/mash/repository/vint/ns-2/atmscheduler.h,v 1.0 2000/07/22 22:46 sow Exp $
+ *
+ * Contributed by Sowmya Manjanatha, Dept. of Computer Science, UNH, July 2000 
+ */
+
+#include "atmscheduler.h"
+
+static class AtmSchedulerClass : public TclClass {
+public:
+	AtmSchedulerClass() : TclClass("AtmScheduler") {}
+	TclObject* create(int, const char*const*) {
+		return (new AtmScheduler);
+		
+	}	
+} class_atmscheduler;
+
+
+inline void AtmSchedulerHandler::handle(Event *e)
+{
+	scheduler->resume();
+}
+
+AtmScheduler::AtmScheduler() : Connector(),handler(this),idle_(true) { 
+
+	last_served_category = -1;
+	
+	for (int i=0; i < NUM_CATEGORIES; i++)
+		last_served_queue_in_category[i] = -1;
+
+	bind ("bytes-per-round",&bytes_per_round);
+
+	// only for debugging purposes
+	AtmQueue t = AtmQueue(0,0);
+	per_vc_q[CBR].push_back(t);
+
+	tx_cells = 0;
+	rx_cells = 0;
+	drops = 0;
+	undequeued  = 0;
+}
+
+
+void AtmScheduler::recv(Packet *p, Handler *h) {
+
+	hdr_atm *atmh = hdr_atm::access(p);
+
+	update_total_input_rate(atmh->vpi,atmh->vci);
+
+	rx_cells++;
+
+
+	//		printf("AtmScheduler::recv, vpi/vci = %d/%d, type = %d\n", atmh->vpi,atmh->vci,atmh->type);
+
+	bool enqueued = enque(p);
+
+	if (enqueued == false) 
+		{
+			//			printf("AtmScheduler : packet being dropped, time = %e\n",Scheduler::instance().clock());
+			drops++;
+			drop(p);
+		}
+	
+	
+	if (idle_ && enqueued) {
+		idle_ = false;
+		assign_service_sizes_per_category();
+		resume();
+	}  
+	
+
+}
+
+void AtmScheduler::resume() {
+
+	Packet *c;
+
+	// c = per_vc_q[0][0].deque(0);
+
+	c = deque();
+
+	if (c == NULL) {
+		undequeued++;
+		// printf("AtmScheduler::atm_queue length is zero\n");
+		idle_ = true;
+		return;
+	}
+
+	tx_cells++;
+	target_->recv(c,&handler);  
+	
+	
+}
+
+int AtmScheduler::command(int argc, const char*const* argv) {
+
+	unsigned int temp = 0;
+	
+	if (argc == 2) {
+	  if (strcmp (argv[1], "scheduler_statistics") == 0) {
+		  for (int i=0; i <per_vc_q[UBR].size() ; i++) 
+			  temp += per_vc_q[UBR][i].qin_cnt();
+
+		  printf("   %8d     %12d       %7d   %5d   %5d   \n",rx_cells,tx_cells,drops,temp,undequeued);
+	  
+		  return TCL_OK;
+	  }
+	}
+	
+
+
+	if (argc == 3) {
+		// assigning queue lengths
+		if (strcmp("queue-length-cbr",argv[1]) == 0) {
+			cbr_qlength = atoi(argv[2]);
+
+			if (cbr_qlength < 0)
+				return TCL_ERROR;
+			return TCL_OK;
+		}
+
+		if (strcmp("queue-length-rt-vbr",argv[1]) == 0) {
+			rt_vbr_qlength = atoi(argv[2]);
+
+			if (rt_vbr_qlength < 0)
+				return TCL_ERROR;
+			return TCL_OK;
+		}
+
+		if (strcmp("queue-length-nrt-vbr",argv[1]) == 0) {
+			nrt_vbr_qlength = atoi(argv[2]);
+
+			if (nrt_vbr_qlength < 0)
+				return TCL_ERROR;
+			return TCL_OK;
+		}
+
+		if (strcmp("queue-length-abr",argv[1]) == 0) {
+			abr_qlength = atoi(argv[2]);
+
+			if (abr_qlength < 0)
+				return TCL_ERROR;
+			return TCL_OK;
+		}
+
+		if (strcmp("queue-length-ubr",argv[1]) == 0) {
+			ubr_qlength = atoi(argv[2]);
+
+			if (ubr_qlength < 0)
+				return TCL_ERROR;
+			return TCL_OK;
+		}
+
+		if (strcmp("queue-length-gfr",argv[1]) == 0) {
+			gfr_qlength = atoi(argv[2]);
+
+			if (gfr_qlength < 0)
+				return TCL_ERROR;
+			return TCL_OK;
+		}
+
+		//assigning queue weights
+		if (strcmp("queue-weight-cbr",argv[1]) == 0) {
+			cbr_qweight = atof(argv[2]);
+
+			if (cbr_qlength < 0.0)
+				return TCL_ERROR;
+			return TCL_OK;
+		}
+
+		if (strcmp("queue-weight-rt-vbr",argv[1]) == 0) {
+			rt_vbr_qweight = atof(argv[2]);
+
+			if (rt_vbr_qweight < 0.0)
+				return TCL_ERROR;
+			return TCL_OK;
+		}
+
+		if (strcmp("queue-weight-nrt-vbr",argv[1]) == 0) {
+			nrt_vbr_qweight = atof(argv[2]);
+
+			if (nrt_vbr_qweight < 0.0)
+				return TCL_ERROR;
+			return TCL_OK;
+		}
+
+		if (strcmp("queue-weight-abr",argv[1]) == 0) {
+			abr_qweight = atof(argv[2]);
+
+			if (abr_qweight < 0.0)
+				return TCL_ERROR;
+			return TCL_OK;
+		}
+
+		if (strcmp("queue-weight-ubr",argv[1]) == 0) {
+			ubr_qweight = atof(argv[2]);
+
+			if (ubr_qweight < 0.0)
+				return TCL_ERROR;
+			return TCL_OK;
+		}
+
+		if (strcmp("queue-weight-gfr",argv[1]) == 0) {
+			gfr_qweight = atof(argv[2]);
+
+			if (gfr_qweight < 0.0)
+				return TCL_ERROR;
+			return TCL_OK;
+		}
+
+		if (strcmp("attach-pvc_dbase",argv[1]) == 0) {
+			pvc_dbase = (pvc_db *) TclObject::lookup(argv[2]);
+			return TCL_OK;
+		}
+	}
+
+	return (Connector::command(argc,argv));
+}
+
+
+void AtmScheduler::reset() {
+
+}
+
+
+//finds the per-vc-queue given vpi and vci values
+ int AtmScheduler::pvc_found(int vp, int vc,int type) {
+	
+	 for (unsigned int i=0; i < per_vc_q[type].size(); i++) {
+		 if ((vp == per_vc_q[type][i].get_vpi()) && (vc == per_vc_q[type][i].get_vci()))
+			 return (int)i;
+	 }
+	 
+	 return -1;
+ }
+ 
+ bool AtmScheduler::enque(Packet *p) {
+	 hdr_atm *atmh = hdr_atm::access(p);
+	 AtmTrafprm *txtp;
+
+	 PVC *pvc = pvc_dbase->get_corresponding_outgoing_pvc(atmh->vpi,atmh->vci);
+
+
+	 if (pvc != NULL)
+		 txtp = pvc->get_txtp();
+	 
+	 else {
+		 printf("AtmScheduler::packet vpi/vci = %d/%d\n",atmh->vpi,atmh->vci);
+
+		 printf("AtmScheduler::enque, PVC NOT found\n");
+		 return false;
+	 }
+	 int i;
+	 
+	 if ((i=pvc_found(atmh->vpi,atmh->vci,txtp->traffic_class)) > -1) {
+		 if (atmh->clp == 0)
+			 return per_vc_q[txtp->traffic_class][i].enque(p,0);
+		 else 
+			 return per_vc_q[txtp->traffic_class][i].enque(p,1);
+	 }
+	 
+	 else {
+		 AtmQueue temp_q(atmh->vpi,atmh->vci);
+		 per_vc_q[txtp->traffic_class].push_back(temp_q);
+		 i = per_vc_q[txtp->traffic_class].size() - 1;
+		 if (atmh->clp == 0)
+			 return per_vc_q[txtp->traffic_class][i].enque(p,0);
+		 else 
+			 return per_vc_q[txtp->traffic_class][i].enque(p,1);
+	 } 
+ }
+ 
+ 
+ void AtmScheduler::assign_service_sizes_per_category () {
+	 
+	 double b = (double)bytes_per_round;
+	 double c = (double)CELLSIZE;
+
+	 cells_per_category[CBR]     = (int)((b * cbr_qweight)/c);
+	 cells_per_category[rt_VBR]  = (int)((b * rt_vbr_qweight)/c);
+	 cells_per_category[nrt_VBR] = (int)((b * nrt_vbr_qweight)/c);
+	 cells_per_category[ABR]     = (int)((b * abr_qweight)/c);
+	 cells_per_category[UBR]     = (int)((b * ubr_qweight)/c);
+	 cells_per_category[GFR]     = (int)((b * gfr_qweight)/c);
+ }
+ 
+
+void AtmScheduler::update_total_input_rate(int vp, int vc) {
+
+	path *entry = pvc_dbase->get_corresponding_table_entry(vp,vc);
+	double t =  Scheduler::instance().clock();
+
+	if (entry != NULL) {
+		double curr_rate = 1/(t - entry->prev_cell_arrival_time);
+		entry->input_rate = (entry->input_rate + curr_rate)/2;
+		total_input_rate = pvc_dbase->get_total_input_rate();
+	}
+
+}
+	
+Packet *AtmScheduler::deque_old() {
+	
+	Packet *p;
+	int q_trav=0;
+	
+	
+	int curr_ctgry = last_served_category+1;
+	int curr_q     = last_served_queue_in_category[curr_ctgry]+1;
+	int ctgries    = NUM_CATEGORIES;
+	int ctgry_trav=0;
+	
+	
+	int i = curr_ctgry;
+	while (i < ctgries)
+		{
+			ctgry_trav++;
+			p = per_vc_queuing(curr_q,per_vc_q[i].size(),i,q_trav);
+			
+			if(p)
+				{
+					last_served_category=i;
+					return p;
+				}
+
+			else if((!p) && (q_trav < (int)per_vc_q[i].size())) 
+				{
+				if(per_vc_queuing(0,curr_q,i,q_trav) != NULL)
+					{
+						last_served_category = i;
+						return p;
+					}
+				}
+
+			if ((i==(ctgries-1)) && (ctgry_trav < ctgries))
+				{
+					i=-1;
+					ctgries=curr_ctgry;
+				}
+
+			i++;
+			
+		}
+	
+	idle_ = true;
+	return (Packet *)NULL;
+}
+
+/* Description :  per_vc_queueing traverses the list of queues w.r.t the category input
+                  and finds a packet if available on a fifo basis */
+ 
+Packet *AtmScheduler::per_vc_queuing(int start, int end, int ctgry, int &q_trvsed)
+{
+	Packet *p;
+
+	for(int i=start; i < end; i++) 
+		{
+			for(int clp=0; clp < 2; clp++)
+				{
+					q_trvsed++;
+					if((p=per_vc_q[ctgry][i].deque(clp)) != NULL) {
+							last_served_queue_in_category[ctgry] = i;
+							return p;
+					}
+				}  
+					    
+		}
+
+	return (Packet *)NULL;
+
+}
+
+
+Packet *AtmScheduler::deque() {
+	
+	return priority_scheduler();
+}
+	
+
+
+/* This is a simple priority scheduler, this method may be used both for per_vc_q scheduling and
+   per_category scheduling where CBR gets the highest priority and UBR gets the least */
+
+Packet *AtmScheduler::priority_scheduler() {
+	
+	Packet *p;
+
+	for (int i=0; i < NUM_CATEGORIES ; i++)
+		if((p=pri_vc_scheduler(i)) != NULL)
+			return p;
+
+	return (Packet*)NULL;
+}
+
+Packet *AtmScheduler::pri_vc_scheduler(int ctgry) {
+	
+	Packet *p;
+
+	for (int i=0 ; i < per_vc_q[ctgry].size() ; i++) {
+
+		for (int clp=0; clp < 2; clp++)
+			if ((p=per_vc_q[ctgry][i].deque(clp)) != NULL)
+				return p;
+	}
+
+	return (Packet *)NULL;
+}
+	
+		
+
+
+
+
+
+
diff -urN ns-2.1b9/atm/atmscheduler.h ns-allinone-2.1b9/ns-2.1b9/atm/atmscheduler.h
--- ns-2.1b9/atm/atmscheduler.h	Wed Dec 31 19:00:00 1969
+++ ns-allinone-2.1b9/ns-2.1b9/atm/atmscheduler.h	Fri Jul 12 15:06:41 2002
@@ -0,0 +1,149 @@
+/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
+/*
+ * Copyright (c) 2000 Regents of the University of New Hampshire.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the MASH Research
+ *      Group at the University of California Berkeley.
+ * 4. Neither the name of the University nor of the Research Group may be
+ *    used to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * 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.
+ *
+ * @(#) $Header: /opt/src/mash/repository/vint/ns-2/atmscheduler.h,v 1.0 2000/07/22 22:46 sow Exp $
+ *
+ * Contributed by Sowmya Manjanatha, Dept. of Computer Science, UNH, July 2000 
+ */
+
+#ifndef __atmscheduler_h__
+#define __atmscheduler_h__
+
+#include "connector.h"
+#include "packet.h"
+#include "atmqueue.h"
+#include "atm.h"
+#include "atmpvc.h"
+
+#define NUM_CATEGORIES 6
+#define MAX_Q 20
+#define CELLS_PER_ROUND 1
+
+
+char qosT[NUM_CATEGORIES][10] = {"cbr", "rt-vbr", "nrt-vbr", "abr", "ubr",
+                                 "gfr"};
+
+class AtmScheduler;
+
+class AtmSchedulerHandler : public Handler {
+public:
+	AtmSchedulerHandler(AtmScheduler *scheduler_i) : scheduler(scheduler_i) { }
+	virtual ~AtmSchedulerHandler() {}
+	void handle(Event *e);
+
+private:
+	AtmScheduler *scheduler;
+	
+};
+
+
+class AtmScheduler : public Connector {
+public:
+	AtmScheduler();
+	void recv(Packet *p, Handler *);
+	void resume();
+	void reset();
+
+protected:
+	AtmSchedulerHandler handler;
+	int command(int argc, const char*const* argv);
+	bool enque(Packet *p);
+	int pvc_found(int,int,int);
+	void assign_service_sizes_per_category();
+	void update_total_input_rate(int,int);
+	Packet *deque();
+	Packet *deque_old();
+	Packet *priority_scheduler();
+	Packet *pri_vc_scheduler(int);
+	Packet *per_vc_queuing(int,int,int,int &);
+	Packet *wrr_scheduler();
+	Packet *wrr_vc_scheduler(int);
+	Packet *WRR_vc_scheduler(int);
+        bool gcra_helper(Packet *,int);
+        bool gcra(double T, double tau, int c, int q); 
+        int set_qlength(const char*const*);
+        int set_qweight(const char*const*);
+        void cells_per_q(int);
+	
+	bool idle_;
+	
+private:
+
+	vector<AtmQueue> per_vc_q[NUM_CATEGORIES];
+	int cbr_qlength;
+	int rt_vbr_qlength;
+	int nrt_vbr_qlength;
+	int gfr_qlength;
+	int abr_qlength;
+	int ubr_qlength;
+        int qlen_[NUM_CATEGORIES][MAX_Q];
+        double tat_[NUM_CATEGORIES][MAX_Q];
+        int wrrTemp[NUM_CATEGORIES][MAX_Q];
+        int qWeight[NUM_CATEGORIES][MAX_Q];
+
+	double cbr_qweight;
+	double rt_vbr_qweight;
+	double nrt_vbr_qweight;
+	double gfr_qweight;
+	double abr_qweight;
+	double ubr_qweight;
+
+	int bytes_per_round;
+	pvc_db *pvc_dbase;
+	int cells_per_category[6];
+	double total_input_rate;
+	double fair_share;
+	double vcshare;
+	double er;
+	double lf;
+	int last_served_category;
+	int last_served_queue_in_category[NUM_CATEGORIES];
+        int last_served_q;
+        int cells_per_round[MAX_Q];
+
+
+
+	//statistics
+	
+	unsigned int rx_cells;
+	unsigned int tx_cells;
+	unsigned int drops;
+	unsigned int undequeued;
+
+};
+
+#endif
+
+
+
+
diff -urN ns-2.1b9/atm/general.h ns-allinone-2.1b9/ns-2.1b9/atm/general.h
--- ns-2.1b9/atm/general.h	Wed Dec 31 19:00:00 1969
+++ ns-allinone-2.1b9/ns-2.1b9/atm/general.h	Fri Jul 12 15:06:41 2002
@@ -0,0 +1,73 @@
+/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
+/*
+ * Copyright (c) 2000 Regents of the University of New Hampshire.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the MASH Research
+ *      Group at the University of California Berkeley.
+ * 4. Neither the name of the University nor of the Research Group may be
+ *    used to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * 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.
+ *
+ * @(#) $Header: /opt/src/mash/repository/vint/ns-2/cell.h,v 1.0 2000/07/22 22:4
+6 sow Exp $
+ *
+ * Contributed by Sowmya Manjanatha, Dept. of Computer Science, UNH, July 2000
+ */
+
+#ifndef __general_h__
+#define __general_h__
+
+class AtmTrafprm;
+
+#define SAMPLERATE 8000
+
+class Reassembly {
+
+public:
+        int vpi;
+        int vci;
+        AtmTrafprm *rxtp;
+        AtmTrafprm *txtp;
+        int tx_cell_cnt;
+        int rx_cell_cnt;
+};
+
+// These info are required for all the UPC functions used by GFR.
+
+class gfr_info {
+public:
+	gfr_info(int vp, int vc, int c) : vpi(vp),vci(vc),clp(c) 
+	{ }
+	int vpi;
+	int vci;
+	int clp;
+	int gfr_cells;
+};
+
+#endif
+
+
+
diff -urN ns-2.1b9/atm/leakybucket.h ns-allinone-2.1b9/ns-2.1b9/atm/leakybucket.h
--- ns-2.1b9/atm/leakybucket.h	Wed Dec 31 19:00:00 1969
+++ ns-allinone-2.1b9/ns-2.1b9/atm/leakybucket.h	Fri Jul 12 15:06:41 2002
@@ -0,0 +1,25 @@
+
+#ifndef __leakybucket_h__
+#define __leakybucket_h__
+
+#include <packet.h>
+
+class VCBuffer{
+
+ public:
+  VCBuffer(int vp,int vc) : vpi_(vp), vci_(vc) 
+    { }
+  int vpi() { return vpi_; }
+  int vci() { return vci_; }
+  int size() { return bucket_.size(); }
+  void erase() { bucket_.erase(bucket_.begin()); }
+  Packet *first() { return (Packet *)(*(bucket_.begin())); }
+  void push_back(Packet *p) { bucket_.push_back(p); }
+
+ private:
+  int vpi_;
+  int vci_;
+  vector <Packet *> bucket_;
+};
+
+#endif
diff -urN ns-2.1b9/atm/map-ds.cc ns-allinone-2.1b9/ns-2.1b9/atm/map-ds.cc
--- ns-2.1b9/atm/map-ds.cc	Wed Dec 31 19:00:00 1969
+++ ns-allinone-2.1b9/ns-2.1b9/atm/map-ds.cc	Fri Jul 12 15:06:41 2002
@@ -0,0 +1,165 @@
+/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
+
+/*
+ * Copyright (c) 1999 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the MASH Research
+ *      Group at the University of California Berkeley.
+ * 4. Neither the name of the University nor of the Research Group may be
+ *    used to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * 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.
+ *
+ * @(#) $Header: /opt/src/mash/repository/vint/ns-2/mapping.h,v 1.0 2001/02/18 14:45:09 sow Exp $
+ *
+ * Contributed by Sowmya Manjanatha, Dept. of Computer Science, UNH, February 2001 
+ */
+
+#include <assert.h>
+#include <stdlib.h>
+
+#include "config.h"
+#include "agent.h"
+#include "ip.h"
+#include "map-ds.h"
+
+static class Map_DSClass : public TclClass {
+public:
+        Map_DSClass() : TclClass("Map_DS") {}
+        TclObject* create(int, const char*const*) {
+                return (new Map_DS(MAP_NONE));
+        }
+} class_map_ds;
+
+
+//Mapping based on Rudiger Geib's proposal
+
+static class Map_GeibClass : public TclClass {
+public:
+        Map_GeibClass() : TclClass("Map_DS/Geib") {}
+        TclObject* create(int, const char*const*) {
+                return (new Map_Geib());
+        }
+} class_map_geib;
+
+
+
+//Mapping based on ATM Forum's proposal
+
+static class Map_AtmfClass : public TclClass {
+public:
+        Map_AtmfClass() : TclClass("Map_DS/ATMF") {}
+        TclObject* create(int, const char*const*) {
+                return (new Map_Atmf());
+        }
+} class_map_atmf;
+
+
+//destructor
+
+Map_DS::~Map_DS() { }
+
+//tcl interface
+
+int Map_DS::command(int argc, const char*const* argv) {
+
+	return (TclObject::command(argc,argv));
+}
+
+//Mapping based on Ayandeh et. al's proposal
+
+static class Map_AyandehClass : public TclClass {
+public:
+        Map_AyandehClass() : TclClass("Map_DS/Ayandeh") {}
+        TclObject* create(int, const char*const*) {
+                return (new Map_Ayandeh());
+        }
+} class_map_ayandeh;
+
+
+Map_Geib::Map_Geib() : Map_DS(MAP_GEIB) {
+
+}
+
+// All the actual mapping functions are found after this line
+
+void Map_Geib::map_ef(Packet *p) {
+
+
+
+}
+
+
+void Map_Geib::map_af(Packet *p) {
+
+
+
+}
+
+void Map_Geib::map_be(Packet *p) {
+
+
+
+}
+
+
+void Map_Atmf::map_ef(Packet *p) {
+
+
+
+}
+
+
+void Map_Atmf::map_af(Packet *p) {
+
+
+
+}
+
+void Map_Atmf::map_be(Packet *p) {
+
+
+
+}
+
+
+void Map_Ayandeh::map_ef(Packet *p) {
+
+
+
+}
+
+
+void Map_Ayandeh::map_af(Packet *p) {
+
+
+
+}
+void Map_Ayandeh::map_be(Packet *p) {
+
+
+
+}
+
diff -urN ns-2.1b9/atm/map-ds.h ns-allinone-2.1b9/ns-2.1b9/atm/map-ds.h
--- ns-2.1b9/atm/map-ds.h	Wed Dec 31 19:00:00 1969
+++ ns-allinone-2.1b9/ns-2.1b9/atm/map-ds.h	Fri Jul 12 15:06:41 2002
@@ -0,0 +1,113 @@
+/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
+
+/*
+ * Copyright (c) 1999 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the MASH Research
+ *      Group at the University of California Berkeley.
+ * 4. Neither the name of the University nor of the Research Group may be
+ *    used to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * 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.
+ *
+ * @(#) $Header: /opt/src/mash/repository/vint/ns-2/map-ds.h,v 1.0 2001/02/18 14:45:09 sow Exp $
+ *
+ * Contributed by Sowmya Manjanatha, Dept. of Computer Science, UNH, February 2001 
+ */
+
+
+#ifndef __map_ds_h__
+#define __map_ds_h__
+
+#include "atm.h"
+
+// Types of mapping addressed
+enum map_t {
+
+	MAP_GEIB,
+	MAP_ATMF,
+	MAP_AYANDEH,
+	MAP_NONE
+	
+};
+
+class Map_DS : public Connector {
+
+public:
+
+	Map_DS(map_t s) : mapType(s) { }
+	virtual ~Map_DS();
+
+protected:
+
+	int command(int argc, const char*const* argv);
+	virtual void map_af(Packet *p) { }
+	virtual void map_ef(Packet *p) { }
+	virtual void map_be(Packet *p) { }
+	map_t mapType;
+
+};
+
+
+class Map_Ayandeh : public Map_DS {
+public:
+	Map_Ayandeh::Map_Ayandeh() : Map_DS(MAP_AYANDEH) { }
+protected:
+	void map_af(Packet *);
+	void map_ef(Packet *);
+	void map_be(Packet *);
+
+private:
+};
+
+
+class Map_Atmf : public Map_DS {
+public:
+	Map_Atmf::Map_Atmf() : Map_DS(MAP_ATMF) { }
+protected:
+	void map_af(Packet *);
+	void map_ef(Packet *);
+	void map_be(Packet *);
+
+private:
+};
+
+
+class Map_Geib : public Map_DS {
+public:
+	Map_Geib::Map_Geib(); // : Map_DS(MAP_GEIB) { }
+protected:
+	void map_af(Packet *);
+	void map_ef(Packet *);
+	void map_be(Packet *);
+
+private:
+};
+
+
+
+
+
+#endif
diff -urN ns-2.1b9/atm/sar.cc ns-allinone-2.1b9/ns-2.1b9/atm/sar.cc
--- ns-2.1b9/atm/sar.cc	Wed Dec 31 19:00:00 1969
+++ ns-allinone-2.1b9/ns-2.1b9/atm/sar.cc	Fri Jul 12 15:06:41 2002
@@ -0,0 +1,381 @@
+/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
+/*
+ * Copyright (c) 2000 Regents of the University of New Hampshire.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the MASH Research
+ *      Group at the University of California Berkeley.
+ * 4. Neither the name of the University nor of the Research Group may be
+ *    used to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * 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.
+ *
+ * @(#) $Header: /opt/src/mash/repository/vint/ns-2/sar.cc,v 1.0 2000/08/15 10:37 sow Exp $
+ *
+ * Contributed by Sowmya Manjanatha, Dept. of Computer Science, UNH, August 2000 
+ */
+
+#include <stdlib.h>
+#include <string>
+#include "config.h"
+#include "sar.h"
+
+char *decode_bool(bool);
+
+static class ATMHeaderClass : public PacketHeaderClass {
+public:
+	ATMHeaderClass() : PacketHeaderClass("PacketHeader/ATM",
+		sizeof(hdr_atm)) {}
+} class_atmhdr;
+
+
+static class SARDriverClass : public TclClass {
+public:
+  SARDriverClass() : TclClass("Agent/SARDriver") {}
+  TclObject* create(int, const char*const*) {
+    return (new SARDriver());
+  }
+} class_sardriver;
+
+
+void SARTimer::expire(Event *)
+{
+	sar_->timeout();
+}
+
+
+SARDriver::SARDriver() : Agent(PT_ATM), timer_(this)
+{
+	bind("packetSize_", &size_);
+	bind("delay_",&delay_);
+	bind("bw_",&bw_);
+	atm = false;
+	atmswitch = false;
+	cell_cnt_for_abr = -1;
+	bw_ = 0.0;
+	delay_ = 0.0;
+	sar_q = new PacketQueue;
+	alwd_cell_cnt = 0;
+	aal = new AAL5;
+
+	//initializing statistics variables
+	rx_pkts = 0;
+	tx_cells = 0;
+	cells_per_pkt = 0;
+
+}
+
+SARDriver::SARDriver(packet_t type) : Agent(type), timer_(this)
+{
+
+}
+
+void SARDriver::start_timer()
+{
+	timer_.sched(txtime()+delay_);
+
+}
+
+void SARDriver::timeout()
+{
+
+	Packet *p = sar_q->deque();
+
+
+	if (p != NULL) {
+                // printf("SARDriver::sar_q len = %d\n",sar_q->length());
+		tx_cells++;
+		target_->recv(p);
+	}
+
+	double t = next_time();
+
+	if (t > 0)
+		timer_.resched(t);
+
+}
+
+
+double SARDriver::next_time()
+{
+	return (txtime() + delay_);
+}
+
+	
+int SARDriver::command(int argc, const char*const* argv)
+{
+  Tcl &tcl = Tcl::instance();
+
+  if(argc == 2) {
+	  if (strcmp(argv[1], "is_atmswitch") == 0) {
+		  atmswitch = true;
+		  return (TCL_OK);
+	  }
+	  
+	  if (strcmp (argv[1], "set-atm") == 0) {
+		  atm = true;
+		  return (TCL_OK);
+	  }
+
+	  if (strcmp (argv[1], "sardriver_statistics") == 0) {
+		  printf("   %8d             %12d                      \n",rx_pkts,tx_cells);
+	  
+		  return TCL_OK;
+	  }
+  }
+  else if(argc == 3) {
+	  if(strcmp(argv[1], "configure_atmswitch") == 0) {
+		  pvc_database = (pvc_db*)TclObject::lookup(argv[2]);
+		  if(pvc_database == NULL) {
+			  tcl.resultf("SARDriver::invalid pvc_database value %s\n",argv[2]);
+			  return TCL_ERROR;
+		  }
+		  return TCL_OK;
+		  
+	  }
+	  
+  } else if (argc == 4) {
+	  
+	  if (strcmp(argv[1], "start_timer") == 0) {
+		  delay_ = atof(argv[2]);
+		  bw_ = atof(argv[3]);
+		  
+		  start_timer();
+	  }
+	  
+	  return TCL_OK;
+	  
+  } else if (argc == 7)  {   /* ATM extn - CNRG, UNH */
+				// enabling IP over ATM support
+	  if(strcmp(argv[1], "attach_aal5") == 0) {
+		  
+		  atm = true;
+		  Reassembly *r= new Reassembly;
+		  r->vpi = atoi(argv[2]);
+		  r->vci = atoi(argv[3]);
+		  r->rxtp = (AtmTrafprm*)TclObject::lookup(argv[4]);
+		  r->txtp = (AtmTrafprm*)TclObject::lookup(argv[5]);
+		  string type = string(argv[6]);
+
+		  aal->set_parameters(r,type);
+		  
+		  
+		  /* if abr, RM cells must be generated after every
+		     cell_cnt_for_abr = (nrm - 1), hence initialize
+		     cell_cnt_for_abr to 0.  Note this also indicates
+		     whether traffic class is abr or not. */
+		  
+		  if((r->txtp)->traffic_class == ABR) {
+			  cell_cnt_for_abr = 0;
+		  }
+		  
+		  return TCL_OK;
+	  }
+    
+    
+  }
+  
+  return Agent::command(argc,argv);
+}
+
+void SARDriver::recv(Packet *p, Handler *h)
+{
+
+	string s = string("src_aal");
+	string d = string("dst_aal");
+
+        hdr_cmn *th = hdr_cmn::access(p);
+        hdr_atm *atmh = hdr_atm::access(p);
+ 
+	if ((atm) && !(p->is_atm()) && (!atmswitch) && (aal->aal_type() == s)) {
+		rx_pkts++;
+		aal5_segmentation(p,h);
+	}
+
+	else if ((atm) && (p->is_atm()) && (!atmswitch)) {
+		printf("SAR::received brm from classifier, I am %s\n",name());
+		send_brm(p,h);
+	}
+
+	else {
+		send(p,h);
+		//target_->recv(p,h);    
+	}
+}
+
+
+void SARDriver::send_brm(Packet *p, Handler *h) {
+	
+	hdr_atm *atmh = hdr_atm::access(p);
+
+	printf("SARDRIVER :: send_brm function, p = 0x%x\n",p);
+	//this is a brm cell which must be sent back to source
+	if ( (atmh->type == ATM_RM) && (atmh->payload->at(8) == '1')) {
+		aal->reverse_addresses_for_brm(p);
+		send(p,h);
+	}
+
+	else
+		target_->recv(p,h);
+}
+
+// aal5_segmentation converts the incoming packets into ATM celss
+// before forwarding it to the appropriate destination.
+
+void SARDriver::aal5_segmentation(Packet *p, Handler *h) {
+
+	Packet **c;
+	int i = 0;
+	Scheduler &s = Scheduler::instance();
+	
+	hdr_ip *iph = hdr_ip::access(p);
+	c=aal->segment(p);
+
+
+	AtmTrafprm *txtp = (aal->get_reassembly()).txtp;
+
+	while (hdr_atm::access(c[i])->type == 0) {
+
+		if (txtp->traffic_class == ABR) {
+
+			process_abr(c[i],h);
+		}
+
+		else {
+			sar_q->enque(c[i]);
+		}
+
+		i++;
+		
+	}
+
+	// this is the last cell of the pdu
+
+	if (txtp->traffic_class == ABR)
+		process_abr(c[i],h);
+
+	else 
+		sar_q->enque(c[i]);
+
+}
+
+void SARDriver::resume()
+{
+	Packet *p = sar_q->deque();
+	
+
+}
+
+
+
+/* If the source is of ABR type, then it is expected to adjust
+   its rate dynamically with respect to the feedback from the 
+   network.  This is done through a set of Resource Management (RM)
+   cells in ATM.  The source generates an RM for every N data cells
+   generated.  This part of the code is  taking care of this process.
+*/
+
+
+void SARDriver::process_abr(Packet *c, Handler *h) 
+{
+	alwd_cell_cnt += aal->allowable_cell_cnt();
+
+	/* first send all the previously buffered cells */
+
+	while ((alwd_cell_cnt > 0) && (aal->abr_buffer_size() > 0)) {
+		Packet *ap = aal->pop_abr();
+		printf("getting packet out of abr buffer,ap = 0x%x\n",ap);
+		forward_abr(ap);
+	}
+
+	// now the received cell if allowable
+	if (alwd_cell_cnt > 0) {
+		forward_abr(c);
+	}
+	else {
+		printf("SARDriver::storing in aal buffer\n");
+		aal->store_in_abr_buffer(c);
+	}
+
+
+}
+
+void SARDriver::forward_abr(Packet *c)
+{
+	if (cell_cnt_for_abr < (aal->get_reassembly().txtp)->nrm) {
+		printf("SARDriver::forward_abr,c = 0x%x\n",c);
+
+		cell_cnt_for_abr++;
+		alwd_cell_cnt--;
+		sar_q->enque(c);
+	}	
+	
+	else {
+		Packet *frm = aal->build_frm(c);
+		printf("SAR:: sending frm, frm = 0x%x\n",frm);
+		alwd_cell_cnt--;
+		sar_q->enque(frm);
+		cell_cnt_for_abr = 0;
+
+		if (alwd_cell_cnt > 0) {
+			cell_cnt_for_abr++;
+			alwd_cell_cnt--;
+			sar_q->enque(c);
+		}
+
+		else {
+			printf("SARDRIVER::storing in abr buffer\n");
+			aal->store_in_abr_buffer(c);
+		}
+	}
+	
+}
+
+
+char *decode_bool(bool b) {
+
+      if (b == true)
+	return "true";
+
+      else if (b == false)
+        return "false";
+
+      else
+         return "unknown";
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -urN ns-2.1b9/atm/sar.cc.bak ns-allinone-2.1b9/ns-2.1b9/atm/sar.cc.bak
--- ns-2.1b9/atm/sar.cc.bak	Wed Dec 31 19:00:00 1969
+++ ns-allinone-2.1b9/ns-2.1b9/atm/sar.cc.bak	Fri Jul 12 15:06:41 2002
@@ -0,0 +1,377 @@
+/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
+/*
+ * Copyright (c) 2000 Regents of the University of New Hampshire.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the MASH Research
+ *      Group at the University of California Berkeley.
+ * 4. Neither the name of the University nor of the Research Group may be
+ *    used to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * 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.
+ *
+ * @(#) $Header: /opt/src/mash/repository/vint/ns-2/sar.cc,v 1.0 2000/08/15 10:37 sow Exp $
+ *
+ * Contributed by Sowmya Manjanatha, Dept. of Computer Science, UNH, August 2000 
+ */
+
+#include <stdlib.h>
+#include <string>
+#include "config.h"
+#include "sar.h"
+
+static class SARDriverClass : public TclClass {
+public:
+  SARDriverClass() : TclClass("SARDriver") {}
+  TclObject* create(int, const char*const*) {
+    return (new SARDriver());
+  }
+} class_sardriver;
+
+
+SARDriver::SARDriver()
+{
+	atm = false;
+	atmswitch = false;
+	cell_cnt_for_abr = -1;
+	bw_ = 0.0;
+	delay_ = 0.0;
+}
+
+int SARDriver::command(int argc, const char*const* argv)
+{
+  Tcl &tcl = Tcl::instance();
+
+  if(argc == 2) {
+    if (strcmp(argv[1], "is_atmswitch") == 0) {
+      atmswitch = true;
+      return (TCL_OK);
+    }
+
+  }
+
+  else if(argc == 3) {
+    if(strcmp(argv[1], "configure_atmswitch") == 0) {
+      pvc_database = (pvc_db*)TclObject::lookup(argv[2]);
+      if(pvc_database == NULL) {
+	tcl.resultf("SARDriver::invalid pvc_database value %s\n",argv[2]);
+	return TCL_ERROR;
+      }
+      return TCL_OK;
+      
+    }
+
+  } else if (argc == 4) {
+	  
+	  if (strcmp(argv[1], "configure") == 0) {
+		  delay_ = atof(argv[2]);
+		  bw_ = atof(argv[3]);
+	  }
+
+	  return TCL_OK;
+  		  
+  } else if (argc == 7)  {   /* ATM extn - CNRG, UNH */
+				// enabling IP over ATM support
+	  if(strcmp(argv[1], "attach_aal5") == 0) {
+      atm = true;
+      Reassembly r;
+      r.vpi = atoi(argv[2]);
+      r.vci = atoi(argv[3]);
+      r.rxtp = (AtmTrafprm*)TclObject::lookup(argv[4]);
+      r.txtp = (AtmTrafprm*)TclObject::lookup(argv[5]);
+      string type = string(argv[6]);
+      aal.set_parameters(r,type);
+      
+      /* if abr, RM cells must be generated after every
+	 cell_cnt_for_abr = (nrm - 1), hence initialize
+	 cell_cnt_for_abr to 0.  Note this also indicates
+	 whether traffic class is abr or not. */
+      
+      if((r.txtp)->traffic_class == ABR)
+	cell_cnt_for_abr = 0;
+      
+      return TCL_OK;
+    }
+    
+    
+  }
+  
+  return Connector::command(argc,argv);
+}
+
+
+
+
+void SARDriver::recv(Packet *p, Handler *h)
+{
+  
+	printf ("SARDriver:: recv\n");
+	if ((atm) && !(p->is_atm()) && (!atmswitch))
+		aal5_segmentation(p,h);
+        
+	
+	/*	else if ((atm) && (p->is_atm()) && (!atmswitch))
+		aal5_reassembly(p,target_,h); 
+        
+	
+		else if ((atmswitch) && (p->is_atm()))
+	switching(p,target_,h); */
+	
+	else 
+		target_->recv(p,h);    
+}
+
+
+void SARDriver::handle(Event *e)
+{
+
+
+}
+
+
+
+// aal5_segmentation converts the incoming packets into ATM celss
+// before forwarding it to the appropriate destination.
+
+void SARDriver::aal5_segmentation(Packet *p, Handler *h) {
+
+	Packet **c;
+	int i = 0;
+	Scheduler &s = Scheduler::instance();
+	
+	c=aal.segment(p);
+	double txt = txtime(p);
+
+
+	while (hdr_atm::access(c[i])->type == 0) {
+
+		if ((aal.get_reassembly().txtp)->traffic_class == ABR) 
+			process_abr(c[i],h);
+
+		else
+			{
+				Event *e = (Event *)c[i];
+				e->time_ = txt + delay_;
+				s.schedule(target_,c[i],txt+delay_);
+				//	s.schedule(this,c[i],txt + delay_);
+				s.schedule(h,&intr_,txt);
+			}
+		i++;
+		
+	}
+
+	// this is the last cell of the pdu
+	Event *e = (Event *)p;
+	e->time_ = txt + delay_;
+	s.schedule(target_,c[i],txt+delay_);
+	s.schedule(h,&intr_,txt);
+	//	s.schedule(this,c[i],txt + delay_);
+
+}
+
+void SARDriver::resume()
+{
+	Packet *p = sar_q->deque();
+	
+
+}
+
+void SARDriver::reset()
+{
+
+
+
+}
+
+//destination node reassembly
+void SARDriver::aal5_reassembly(Packet *p, NsObject *node, Handler *h) {
+	
+	hdr_atm *atmh = hdr_atm::access(p);
+
+	int pi = atmh->vpi;
+	int c = atmh->vci;
+	int tp = atmh->type;
+
+
+	printf("SARDriver: reassembly pkt vpi/vci = %d/%d, type = %d\n",pi,c,tp);
+	
+	/* if this is the first cell of the frame, note down
+	   the vpi/vci marker */
+
+	int vp = aal.get_reassembly().vpi;
+	int vc = aal.get_reassembly().vci;
+
+
+	if((atmh->vpi == vp) && (atmh->vci == vc)) {
+
+		int t = atmh->type;
+
+		// EFCI bit set by switch
+		if(t == 2) 
+			aal.set_efci(); 
+			
+		//the last cell in the pdu
+		if((t == 1) || (t == 3) || (t == 5) || (t == 7)) {
+			printf("last packet of the frame\n");
+
+			// congestion in the network
+			if ((t==3) || (t==7))
+				aal.set_efci();
+			node->recv(atmh->packet,h);
+		}
+
+		// this is an RM cell
+		if (t == 6) 
+			treat_rm_cell(p,node,h);
+					
+	}
+
+}
+
+//atm switch forwarding
+void SARDriver::switching(Packet *p, NsObject *node, Handler *h) {
+	
+	hdr_atm *atmh = hdr_atm::access(p);
+
+	string s = string(atmh->switcher);
+	
+	printf(" This object's name is %s\n",s.c_str());
+
+	if (s != name())
+		{
+
+		  printf("This is the first time in %s\n",name());
+		  PVC *pvc = pvc_database->get_outgoing_pvc(atmh->vpi,atmh->vci);
+		  
+		  /* this should never happen */
+		  if (pvc == NULL) {
+		    atmh->vpi = -1;
+		    atmh->vci = -1;
+		    
+		  } else {
+		    atmh->vpi = pvc->get_vpi();
+		    atmh->vci = pvc->get_vci();
+		  }
+		  atmh->switcher =(char *) (((string)name()).c_str());
+		}
+	
+	
+	
+	node->recv(p,h);
+}
+
+
+
+void SARDriver::treat_rm_cell(Packet *p,NsObject *node, Handler *h) {
+
+	hdr_atm *atmh = hdr_atm::access(p);
+
+	//this is an FRM cell
+	if ((atmh->payload)[8] == '0') {
+		(atmh->payload)[8] = '1';
+		if (aal.get_efci()) 
+			(atmh->payload)[10] = '1';
+		
+		//this is to send back the brm to the source
+		aal.reverse_addresses_for_brm(p);
+
+		NsObject *n = find(p);
+
+		n->recv(p,h);
+	}
+
+	//this is a BRM cell
+	else if((atmh->payload)[8] == '1')
+		aal.adjust_source_rate(p);
+}
+		
+					
+
+/* If the source is of ABR type, then it is expected to adjust
+   its rate dynamically with respect to the feedback from the 
+   network.  This is done through a set of Resource Management (RM)
+   cells in ATM.  The source generates an RM for every N data cells
+   generated.  This part of the code is  taking care of this process.
+*/
+
+
+void SARDriver::process_abr(Packet *c, Handler *h) 
+{
+	int alwd_cell_cnt = aal.allowable_cell_cnt();
+	aal.send_buffered_cells_till_allowable(&alwd_cell_cnt,target_,h);
+	double txt = txtime(c);
+	Scheduler &s = Scheduler::instance();
+	
+
+	if (cell_cnt_for_abr < (aal.get_reassembly().txtp)->nrm) {
+
+		if (alwd_cell_cnt > 0) {
+			cell_cnt_for_abr++;
+			alwd_cell_cnt--;
+			
+
+			s.schedule(target_,c,txt+delay_);
+			s.schedule(h,&intr_,txt);
+			// node->recv(c[i],h);
+		}
+		
+		else 
+			aal.store_in_abr_buffer(c);
+	}
+	else {
+				//generation of RM cells
+		
+		if (alwd_cell_cnt > 0) {
+			Packet *frm = aal.build_frm(c);
+			alwd_cell_cnt--;
+			
+			s.schedule(target_,frm,txt+delay_);
+			s.schedule(h,&intr_,txt);
+			
+			//node->recv(frm,h);
+			
+			if (alwd_cell_cnt > 0) {
+				cell_cnt_for_abr = 1;
+				alwd_cell_cnt--;
+				
+				s.schedule(target_,c,txt+delay_);
+				s.schedule(h,&intr_,txt);
+				// node->recv(c[i],h);
+			}
+			else
+				aal.store_in_abr_buffer(c);
+		}
+	}
+}
+
+
+
+
+
+
+
+
+
+
+
diff -urN ns-2.1b9/atm/sar.h ns-allinone-2.1b9/ns-2.1b9/atm/sar.h
--- ns-2.1b9/atm/sar.h	Wed Dec 31 19:00:00 1969
+++ ns-allinone-2.1b9/ns-2.1b9/atm/sar.h	Fri Jul 12 15:06:41 2002
@@ -0,0 +1,71 @@
+#ifndef __sar_h__
+#define __sar_h__
+
+#include "connector.h"
+#include "packet.h"
+#include "atmqos.h"
+#include "aal.h"
+#include "atm.h"
+#include "atmpvc.h"
+#include "queue.h"
+
+class SARDriver;
+class SARTimer;
+
+class SARTimer : public TimerHandler {
+ public:
+  SARTimer(SARDriver *s) : TimerHandler(), sar_(s) {}
+  inline virtual void expire(Event *);
+ protected:
+  SARDriver *sar_;
+};
+
+
+class SARDriver : public Agent {
+
+ public:
+  SARDriver();
+  SARDriver(packet_t);
+  ~SARDriver() { printf("SAR::destructor\n"); delete sar_q; }
+  void recv(Packet *p, Handler *h);
+  void resume();
+  void timeout();
+  void start_timer();
+
+ protected:
+
+  void aal5_segmentation(Packet *, Handler *);
+  int command(int, const char*const* );
+  NsObject *find(Packet *p) { NsObject *n; return n;} //dummy function, must be changed later
+  inline double txtime() {
+    return (8. * CELLSIZE / bw_);
+  }
+  void process_abr(Packet *, Handler *);
+  inline double next_time();
+  void forward_abr(Packet *);
+  void send_brm(Packet *, Handler *);
+  
+  Event intr_;
+  PacketQueue *sar_q;
+  SARTimer timer_;
+
+ private:
+  bool atm;           
+  AAL5 *aal;         
+  bool atmswitch;
+  int cell_cnt_for_abr;
+  pvc_db *pvc_database;
+  double bw_;
+  double delay_;
+  int off_atm_;
+  int sent_cells;
+  int alwd_cell_cnt;
+
+  //statistics collection
+  unsigned int rx_pkts;
+  unsigned int tx_cells;
+  unsigned int cells_per_pkt;
+  
+};
+
+#endif
diff -urN ns-2.1b9/atm/sar.h.bak ns-allinone-2.1b9/ns-2.1b9/atm/sar.h.bak
--- ns-2.1b9/atm/sar.h.bak	Wed Dec 31 19:00:00 1969
+++ ns-allinone-2.1b9/ns-2.1b9/atm/sar.h.bak	Fri Jul 12 15:06:41 2002
@@ -0,0 +1,50 @@
+#ifndef __sar_h__
+#define __sar_h__
+
+#include "connector.h"
+#include "packet.h"
+#include "atmqos.h"
+#include "aal.h"
+#include "atm.h"
+#include "atmpvc.h"
+#include "queue.h"
+
+
+class SARDriver : public Connector {
+
+ public:
+  SARDriver();
+  void recv(Packet *p, Handler *h);
+  void send(Packet *p, Handler *h) { target_->recv(p, (Handler*)NULL); }
+  void resume();
+  void reset();
+  void handle(Event *e);
+
+ protected:
+
+  void treat_rm_cell(Packet *, NsObject *, Handler *);
+  void aal5_segmentation(Packet *, Handler *);
+  void aal5_reassembly(Packet *, NsObject *, Handler *);
+  void switching(Packet *, NsObject *, Handler *);
+  int command(int, const char*const* );
+  NsObject *find(Packet *p) { NsObject *n; return n;} //dummy function, must be changed later
+  inline double txtime(Packet *p) {
+    return (8. * hdr_cmn::access(p)->size() / bw_);
+  }
+  void process_abr(Packet *, Handler *);
+  
+  Event intr_;
+  PacketQueue *sar_q;
+
+ private:
+  bool atm;           
+  AAL5 aal;         
+  bool atmswitch;
+  int cell_cnt_for_abr;
+  pvc_db *pvc_database;
+  double bw_;
+  double delay_;
+  
+};
+
+#endif
diff -urN ns-2.1b9/classifier/classifier.cc ns-allinone-2.1b9/ns-2.1b9/classifier/classifier.cc
--- ns-2.1b9/classifier/classifier.cc	Wed Mar 20 21:14:34 2002
+++ ns-allinone-2.1b9/ns-2.1b9/classifier/classifier.cc	Fri Jul 12 16:12:16 2002
@@ -32,6 +32,11 @@
  * SUCH DAMAGE.
  */
 
+/* ********************************************************************* *
+ *   THE ATM PORT FOR THIS FILE IS COMPLETED                             *
+ * ********************************************************************* */
+
+
 #ifndef lint
 static const char rcsid[] =
     "@(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/classifier/classifier.cc,v 1.41 2002/03/21 01:46:02 johnh Exp $";
@@ -42,6 +47,12 @@
 #include "classifier.h"
 #include "packet.h"
 
+// ATM PATCH CNRG, UNH
+#include <string>
+#include "atm/atmpvc.h"
+#include "atm/aal.h"
+
+
 static class ClassifierClass : public TclClass {
 public:
 	ClassifierClass() : TclClass("Classifier") {}
@@ -51,9 +62,13 @@
 } class_classifier;
 
 
+/* ATM port for this constructor is done */
+/* CNRG University of New Hampshire */
 Classifier::Classifier() : 
-	slot_(0), nslot_(0), maxslot_(-1), shift_(0), mask_(0xffffffff), nsize_(0)
+	slot_(0), nslot_(0), maxslot_(-1), shift_(0), mask_(0xffffffff), nsize_(0),
+	atm(false), atmswitch(false), cell_cnt_for_abr(-1) 
 {
+	aal = new AAL5;
 	default_target_ = 0;
 
 	bind("offset_", &offset_);
@@ -66,9 +81,12 @@
 	return (mshift(*((int*) p->access(offset_))));
 }
 
+/* ATM port for this constructor is done */
+/* CNRG University of New Hampshire */
 Classifier::~Classifier()
 {
 	delete [] slot_;
+	delete aal;
 }
 
 void Classifier::set_table_size(int nn)
@@ -128,12 +146,16 @@
 	return i;
 }
 
+/* ATM port for this constructor is done */
+/* CNRG University of New Hampshire */
+
 /*
  * objects only ever see "packet" events, which come either
  * from an incoming link or a local agent (i.e., packet source).
  */
 void Classifier::recv(Packet* p, Handler*h)
 {
+	hdr_atm *atmh;
 	NsObject* node = find(p);
 	if (node == NULL) {
 		/*
@@ -143,7 +165,53 @@
 		Packet::free(p);
 		return;
 	}
-	node->recv(p,h);
+
+       //ATM extension, CNRG, UNH
+
+        string d = string("dst_aal");
+        string s = string("src_aal");
+
+        if(p->is_atm())
+                {
+                        atmh = hdr_atm::access(p);
+			if ((atmh->vpi == 0) && (atmh->vci == 0))
+				{
+			               printf("Clsfer::dropping packet, id = %s, vpi/vci=%d/%d, time = %e\n",name(),atmh->vpi,atmh->vci,Scheduler::instance().clock());
+					Packet::free(p);
+					return;
+				}
+
+                }
+
+        if ((atm) && (p->is_atm()) && (!atmswitch) && (aal->aal_type() == d))
+                {
+			rx_cells++;
+			aal5_reassembly(p,node,h);
+                }
+
+
+        else if ((atm) && (atmswitch) && (p->is_atm()))
+                {
+                 
+                        switching(p,node,h);
+                }
+
+        else if ((atm) && (p->is_atm()) && (!atmswitch) && (aal->aal_type() == s)) {
+		atmh = hdr_atm::access(p);
+		if ((atmh->type == ATM_RM) && ((atmh->payload)->at(8) == '1')) {
+			printf("Classifier::received BRM cell, I am %s\n",name());
+			aal->adjust_source_rate(p);
+		}
+
+		else {
+			node->recv(p,h);
+		}
+	}
+        else {
+		hdr_cmn *th = hdr_cmn::access(p);
+		node->recv(p,h);                
+	}
+	
 }
 
 /*
@@ -190,6 +258,19 @@
                                 tcl.result(default_target_->name());
                         return (TCL_OK);
                 }
+
+		//ATM extension, CNRG, UNH
+		if (strcmp(argv[1], "atm_statistics") == 0) {
+			printf("   %8d             %12d           \n",rx_cells,tx_pkts);
+		  return TCL_OK;
+		}
+
+                if (strcmp(argv[1], "is_atmswitch") == 0) {
+                        atmswitch = true;
+                        return (TCL_OK);
+                }
+
+
         } else if (argc == 3) {
 		/*
 		 * $classifier alloc-port nullagent
@@ -268,6 +349,19 @@
 				return TCL_ERROR;
 			return TCL_OK;
 		}
+
+		/* ATM extn - CNRG, UNH */
+                if(strcmp(argv[1], "configure_atmswitch") == 0) {
+                        pvc_database = (pvc_db*)TclObject::lookup(argv[2]);
+                        if(pvc_database == NULL) {
+                                tcl.resultf("Classifier::invalid pvc_database va
+lue %s\n",argv[2]);
+                                return TCL_ERROR;
+                        }
+                        atmswitch = true;
+			atm = true;
+                        return TCL_OK;
+                }
 	} else if (argc == 4) {
 		/*
 		 * $classifier install $slot $node
@@ -278,6 +372,188 @@
 			install(slot, node);
 			return (TCL_OK);
 		}
+
+	} else if (argc == 7)  {   /* ATM extn - CNRG, UNH */
+                                // enabling IP over ATM support
+                if(strcmp(argv[1], "attach_aal5") == 0) {
+                        atm = true;
+                        Reassembly *r = new Reassembly;
+                        r->vpi = atoi(argv[2]);
+                        r->vci = atoi(argv[3]);
+                        r->rxtp = (AtmTrafprm*)TclObject::lookup(argv[4]);
+                        r->txtp = (AtmTrafprm*)TclObject::lookup(argv[5]);
+
+                        string type = string(argv[6]);
+                        aal->set_parameters(r, type);
+
+                        /* if abr, RM cells must be generated after every
+                           cell_cnt_for_abr = (nrm - 1), hence initialize
+                           cell_cnt_for_abr to 0.  Note this also indicates
+                           whether traffic class is abr or not. */
+
+                        if((r->txtp)->traffic_class == ABR)
+                                cell_cnt_for_abr = 0;
+
+                        return TCL_OK;
+                }
+
 	}
+
 	return (NsObject::command(argc, argv));
 }
+
+//ATM EXTENSION, CNRG, UNH
+//destination node reassembly
+void Classifier::aal5_reassembly(Packet *p, NsObject *node, Handler *h) {
+
+        hdr_atm *atmh = hdr_atm::access(p);
+	Packet *temp;
+	hdr_cmn *th;
+
+        /* if this is the first cell of the frame, note down
+           the vpi/vci marker */
+	
+        int vp = aal->get_reassembly().vpi;
+        int vc = aal->get_reassembly().vci;
+
+
+        if((atmh->vpi == vp) && (atmh->vci == vc)) {
+
+                int t = atmh->type;
+
+		switch (t) {
+			
+			// EFCI bit set by switch
+		case EFCI:
+                        delete atmh->payload;
+			Packet::free(p);
+			aal->set_efci();
+			break;
+			
+		case EFCI_LAST_CELL:
+		case EFCI_LAST_UNKNOWN:
+			th = hdr_cmn::access(atmh->packet);
+//			printf("Classifier::reassembly, sending packet to agent, vpi/vci=%d/%d, orig pkt_id = %d \n",atmh->vpi,atmh->vci,th->uid());
+
+			tx_pkts++;
+			aal->set_efci();
+                        temp = atmh->packet;
+                        delete atmh->payload;
+	                Packet::free(p);
+                        node->recv(temp,h);
+			break;
+			
+		case EFCI_FIVE:
+		case LAST_CELL:
+			th = hdr_cmn::access(atmh->packet);
+                        temp = atmh->packet;
+//			printf("Classifier::reassembly, sending packet to agent, vpi/vci=%d/%d, orig pkt_id = %d \n",atmh->vpi,atmh->vci,th->uid());
+			tx_pkts++;
+                        delete atmh->payload;
+	                Packet::free(p);
+                        node->recv(temp,h);
+			break;
+			
+			// This packet is not going to be sent to target
+			// Only the reassembled wd. be.  So, free some
+			// resources
+			
+		case ATM_NONE:
+		case ATM_FOUR:
+                        delete atmh->payload;
+			Packet::free(p);
+			break;
+			
+			// this is an RM cell
+		case ATM_RM:
+                        treat_rm_cell(p,node,h);
+			break;
+			
+		default:
+			printf("CLASSIFIER::error in ATM type\n");
+			return;
+		}
+	}
+
+       else {
+           printf("Classifier::dropping packet, vpi/vci did not match\n");
+	   Packet::free(p);
+       }
+        
+
+	return;
+}
+
+
+//atm switch forwarding
+void Classifier::switching(Packet *p, NsObject *node, Handler *h) {
+
+        hdr_atm *atmh = hdr_atm::access(p);
+      //  int cmn = (hdr_cmn::access(atmh->packet))->uid();
+//	int atmp = (hdr_cmn::access(p))->uid();
+
+        string s = string(atmh->switcher_);
+
+        if (s != name())
+                {
+
+                        PVC *pvc = pvc_database->get_outgoing_pvc(atmh->vpi,atmh
+->vci);
+
+                        /* this should never happen */
+                        if (pvc == NULL) {
+                                atmh->vpi = -1;
+                                atmh->vci = -1;
+
+                        } else {
+                                atmh->vpi = pvc->get_vpi();
+                                atmh->vci = pvc->get_vci();
+				strcpy(atmh->switcher_,((string)name()).c_str());
+
+                        }
+
+                }
+
+        node->recv(p,h);
+}
+
+//ATM Extension, CNRG, UNH
+//function to support ABR feedback generator
+
+void Classifier::treat_rm_cell(Packet *p,NsObject *node, Handler *h) {
+
+        hdr_atm *atmh = hdr_atm::access(p);
+
+	cell_cnt++;
+ 
+        //this is an FRM cell
+        if ((atmh->payload)->at(8) == '0') {
+
+		printf ("CLASSIFIER::received FRM CELL %d\n", cell_cnt);
+                (atmh->payload)->at(8) = '1';
+                if (aal->get_efci())
+                        atmh->payload->at(10) = '1';
+
+                //this is to send back the brm to the source
+                // aal->reverse_addresses_for_brm(p);
+
+                NsObject *n = find(p);
+		n->recv(p,h);
+
+        }
+
+        //this is a BRM cell
+        else if(atmh->payload->at(8) == '1') {
+                NsObject *n = find(p);
+		n->recv(p,h);
+        }
+
+	else
+		printf("Classifier::Regular cell  %d\n",cell_cnt);
+
+}
+
+
+
+
+
diff -urN ns-2.1b9/classifier/classifier.h ns-allinone-2.1b9/ns-2.1b9/classifier/classifier.h
--- ns-2.1b9/classifier/classifier.h	Fri Jan 25 16:40:50 2002
+++ ns-allinone-2.1b9/ns-2.1b9/classifier/classifier.h	Fri Jul 12 15:06:41 2002
@@ -34,13 +34,26 @@
  * @(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/classifier/classifier.h,v 1.32 2002/01/25 20:22:16 haldar Exp $ (LBL)
  */
 
+/* ********************************************************************* *
+ *   THE ATM PORT FOR THIS FILE IS COMPLETED                             *
+ * ********************************************************************* */
+
+
 #ifndef ns_classifier_h
 #define ns_classifier_h
 
 #include "object.h"
 
+// ATM PATCH, CNRG, UNH 
+#include "atm/atmqos.h"                                                     /* CNRG */
+#include "atm/atm.h"                                                        /* CNRG */
+
 class Packet;
 
+// ATM PATCH, CNRG, UNH 
+class pvc_db;
+class AAL5;
+
 class Classifier : public NsObject {
 public:
 	Classifier();
@@ -73,11 +86,20 @@
 	void set_table_size(int nn);
 	// hierarchical specific
 	virtual void set_table_size(int level, int nn) {}
-	
+
+        //ATM extension, CNRG, UNH
+        void aal5_reassembly(Packet *, NsObject *, Handler *);
+        void switching(Packet *, NsObject *, Handler *);
+	// END OF ATM extension
+
 protected:
 	virtual int getnxt(NsObject *);
 	virtual int command(int argc, const char*const* argv);
 	void alloc(int);
+
+        //ATM EXTENSION, CNRG, UNH
+        void treat_rm_cell(Packet *,NsObject *,Handler *);
+
 	NsObject** slot_;	/* table that maps slot number to a NsObject */
 	int nslot_;
 	int maxslot_;
@@ -86,6 +108,20 @@
 	int mask_;
 	NsObject *default_target_;
 	int nsize_;       //what size of nslot_ should be
+
+        //ATM extension, CNRG, UNH
+        bool atm;
+        AAL5 *aal;
+        bool atmswitch;
+        int cell_cnt_for_abr;
+        pvc_db *pvc_database;
+	int cell_cnt;
+
+	//ATM statistics
+	unsigned int rx_cells;
+	unsigned int tx_pkts;
+
+
 };
 
 #endif
diff -urN ns-2.1b9/common/packet.h ns-allinone-2.1b9/ns-2.1b9/common/packet.h
--- ns-2.1b9/common/packet.h	Fri Mar 15 12:26:44 2002
+++ ns-allinone-2.1b9/ns-2.1b9/common/packet.h	Fri Jul 12 15:06:41 2002
@@ -33,6 +33,9 @@
  *
  * @(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/common/packet.h,v 1.88 2002/03/14 01:18:09 haldar Exp $ (LBL)
  */
+/* ********************************************************************* *
+ *   THE ATM PORT FOR THIS FILE IS COMPLETED                             *
+ * ********************************************************************* */
 
 #ifndef ns_packet_h
 #define ns_packet_h
@@ -139,6 +142,9 @@
 	// ReadAudio traffic
 	PT_REALAUDIO,
 
+        //ATM extension, CNRG, UNH
+	PT_ATM,
+
 	// Pushback Messages
 	PT_PUSHBACK,
 
@@ -227,6 +233,9 @@
 		name_[PT_PGM] = "PGM";
 #endif
 
+                // ATM packets (cells)
+                name_[PT_ATM] = "atm";
+
 		name_[PT_NTYPE]= "undefined";
 	}
 	const char* name(packet_t p) const { 
@@ -301,13 +310,17 @@
 	AppData* data_;		// variable size buffer for 'data'
 	static void init(Packet*);     // initialize pkt hdr 
 	bool fflag_;
+
+
+        bool atm_;               //ATM extension, CNRG, UNH
+
 protected:
 	static Packet* free_;	// packet free list
 public:
 	Packet* next_;		// for queues and the free list
 	static int hdrlen_;
 
-	Packet() : bits_(0), data_(0), next_(0) { }
+	Packet() : bits_(0), data_(0),atm_(false), next_(0) { }          // CNRG ATM extns
 	inline unsigned char* const bits() { return (bits_); }
 	inline Packet* copy() const;
 	static inline Packet* alloc();
@@ -361,6 +374,11 @@
         u_int8_t        incoming;
 
 	//monarch extns end;
+
+        //ATM extension, CNRG, UNH
+        bool is_atm() { return atm_; }
+        void set_atm() { atm_ = true; }
+        // ATM extn ends
 };
 
 /* 
@@ -500,6 +518,10 @@
 		assert(p->data_ == 0);
 		p->uid_ = 0;
 		p->time_ = 0;
+
+                //ATM extension, CNRG, UNH
+                p->atm_ = false;
+
 	} else {
 		p = new Packet;
 		p->bits_ = new unsigned char[hdrlen_];
diff -urN ns-2.1b9/common/ttl.cc ns-allinone-2.1b9/ns-2.1b9/common/ttl.cc
--- ns-2.1b9/common/ttl.cc	Wed Aug 12 19:41:24 1998
+++ ns-allinone-2.1b9/ns-2.1b9/common/ttl.cc	Fri Jul 12 15:07:20 2002
@@ -32,6 +32,10 @@
  * SUCH DAMAGE.
  */
 
+/* ********************************************************************* *
+ *   THE ATM PORT FOR THIS FILE IS COMPLETED                             *
+ * ********************************************************************* */
+
 #ifndef lint
 static const char rcsid[] =
     "@(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/common/ttl.cc,v 1.11 1998/08/12 23:41:24 gnguyen Exp $";
@@ -68,7 +72,10 @@
 	void recv(Packet* p, Handler* h) {
 		hdr_ip* iph = hdr_ip::access(p);
 		int ttl = iph->ttl() - tick_;
-		if (ttl <= 0) {
+
+
+                // ATM extension, CNRG, UNH
+		if ((!p->is_atm()) && (ttl <= 0)) {
 			/* XXX should send to a drop object.*/
 			// Yes, and now it does...
 			// Packet::free(p);
Binary files ns-2.1b9/indep-utils/cmu-scen-gen/setdest/calcdest and ns-allinone-2.1b9/ns-2.1b9/indep-utils/cmu-scen-gen/setdest/calcdest differ
Binary files ns-2.1b9/indep-utils/cmu-scen-gen/setdest/calcdest.o and ns-allinone-2.1b9/ns-2.1b9/indep-utils/cmu-scen-gen/setdest/calcdest.o differ
Binary files ns-2.1b9/indep-utils/cmu-scen-gen/setdest/rng.o and ns-allinone-2.1b9/ns-2.1b9/indep-utils/cmu-scen-gen/setdest/rng.o differ
Binary files ns-2.1b9/indep-utils/cmu-scen-gen/setdest/setdest and ns-allinone-2.1b9/ns-2.1b9/indep-utils/cmu-scen-gen/setdest/setdest differ
Binary files ns-2.1b9/indep-utils/cmu-scen-gen/setdest/setdest.o and ns-allinone-2.1b9/ns-2.1b9/indep-utils/cmu-scen-gen/setdest/setdest.o differ
Binary files ns-2.1b9/indep-utils/webtrace-conv/dec/dec-tr-stat and ns-allinone-2.1b9/ns-2.1b9/indep-utils/webtrace-conv/dec/dec-tr-stat differ
Binary files ns-2.1b9/indep-utils/webtrace-conv/dec/formsquid.o and ns-allinone-2.1b9/ns-2.1b9/indep-utils/webtrace-conv/dec/formsquid.o differ
Binary files ns-2.1b9/indep-utils/webtrace-conv/dec/formtxt.o and ns-allinone-2.1b9/ns-2.1b9/indep-utils/webtrace-conv/dec/formtxt.o differ
Binary files ns-2.1b9/indep-utils/webtrace-conv/dec/my-endian.o and ns-allinone-2.1b9/ns-2.1b9/indep-utils/webtrace-conv/dec/my-endian.o differ
Binary files ns-2.1b9/indep-utils/webtrace-conv/dec/proxytrace.o and ns-allinone-2.1b9/ns-2.1b9/indep-utils/webtrace-conv/dec/proxytrace.o differ
Binary files ns-2.1b9/indep-utils/webtrace-conv/dec/proxytrace2any.o and ns-allinone-2.1b9/ns-2.1b9/indep-utils/webtrace-conv/dec/proxytrace2any.o differ
Binary files ns-2.1b9/indep-utils/webtrace-conv/dec/tr-stat.o and ns-allinone-2.1b9/ns-2.1b9/indep-utils/webtrace-conv/dec/tr-stat.o differ
Binary files ns-2.1b9/indep-utils/webtrace-conv/epa/epa-tr-stat and ns-allinone-2.1b9/ns-2.1b9/indep-utils/webtrace-conv/epa/epa-tr-stat differ
Binary files ns-2.1b9/indep-utils/webtrace-conv/epa/tr-stat.o and ns-allinone-2.1b9/ns-2.1b9/indep-utils/webtrace-conv/epa/tr-stat.o differ
Binary files ns-2.1b9/indep-utils/webtrace-conv/nlanr/logparse.o and ns-allinone-2.1b9/ns-2.1b9/indep-utils/webtrace-conv/nlanr/logparse.o differ
Binary files ns-2.1b9/indep-utils/webtrace-conv/nlanr/nlanr-tr-stat and ns-allinone-2.1b9/ns-2.1b9/indep-utils/webtrace-conv/nlanr/nlanr-tr-stat differ
Binary files ns-2.1b9/indep-utils/webtrace-conv/nlanr/tr-stat.o and ns-allinone-2.1b9/ns-2.1b9/indep-utils/webtrace-conv/nlanr/tr-stat.o differ
Binary files ns-2.1b9/indep-utils/webtrace-conv/ucb/logparse.o and ns-allinone-2.1b9/ns-2.1b9/indep-utils/webtrace-conv/ucb/logparse.o differ
Binary files ns-2.1b9/indep-utils/webtrace-conv/ucb/tr-stat.o and ns-allinone-2.1b9/ns-2.1b9/indep-utils/webtrace-conv/ucb/tr-stat.o differ
Binary files ns-2.1b9/indep-utils/webtrace-conv/ucb/ucb-tr-stat and ns-allinone-2.1b9/ns-2.1b9/indep-utils/webtrace-conv/ucb/ucb-tr-stat differ
Binary files ns-2.1b9/indep-utils/webtrace-conv/ucb/utils.o and ns-allinone-2.1b9/ns-2.1b9/indep-utils/webtrace-conv/ucb/utils.o differ
diff -urN ns-2.1b9/tcl/lib/ns-atm.tcl ns-allinone-2.1b9/ns-2.1b9/tcl/lib/ns-atm.tcl
--- ns-2.1b9/tcl/lib/ns-atm.tcl	Wed Dec 31 19:00:00 1969
+++ ns-allinone-2.1b9/ns-2.1b9/tcl/lib/ns-atm.tcl	Fri Jul 12 15:07:53 2002
@@ -0,0 +1,237 @@
+#
+# Copyright (c) 2000, CNRG, University of New Hampshire.
+# All rights reserved.
+#
+# License is granted to copy, to use, and to make and to use derivative
+# works for research and evaluation purposes.
+#
+# THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+# WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Contributed by Sowmya Manjanatha <sowmyam@cs.unh.edu>
+#
+#
+
+# insert the conditioner between the end-station and the
+# ATMNode.
+
+# a simple atm link (written to substitue the default with the AtmScheduler)
+Simulator instproc atm-simplex-link {n1 n2 bw delay pvc_dbase args} {
+    global packetsize linkrate rate dly bw_
+
+    
+    set dly $delay 
+    set bw_ $bw
+
+    $self instvar link_
+    set sid [$n1 id]
+    set did [$n2 id]
+    set scheduler [new AtmScheduler]
+
+    set rate [$self bw_parse $bw]
+    set dly [$self delay_parse $delay]
+    $scheduler set total_service_rate_ $rate
+    puts "scheduler = $scheduler"
+    set link_($sid:$did) [new SimpleLink $n1 $n2 $bw $delay $scheduler]
+    $n1 add-neighbor $n2
+
+    set trace [$self get-ns-traceall]
+    if {$trace != ""} {
+	$self trace-queue $n1 $n2 $trace
+    }
+    set trace [$self get-nam-traceall]
+    if {$trace != ""} {
+	$self namtrace-queue $n1 $n2 $trace
+    }
+    $self register-nam-linkconfig $link_($sid:$did)
+    $scheduler attach-pvc_dbase $pvc_dbase
+    $pvc_dbase instvar linknum_
+    $pvc_dbase add-resources $rate $dly $linknum_
+
+    # the scheduler could access the pvc_dbase to be assigned to the
+    # atm node later.  For now, I will  attach the scheduler to the
+    # atm node.
+
+    return $scheduler
+
+}
+
+# an atm duplex-link
+
+Simulator instproc atm-duplex-link {n1 n2 bw delay pvc_dbase pvc_dbase1 args} {
+
+    $n1 instvar scheduler
+    
+    set scheduler(0) [ $self atm-simplex-link $n1 $n2 $bw $delay $pvc_dbase $args]
+    set scheduler(1) [ $self atm-simplex-link $n2 $n1 $bw $delay $pvc_dbase1 $args]
+    
+}
+
+
+# nam support for link orientation, color etc.
+
+Simulator instproc atm-duplex-link-op { n1 n2 op args } {
+    $self instvar link_
+    eval $link_([$n1 id]:[$n2 id]) $op $args
+    eval $link_([$n2 id]:[$n1 id]) $op $args
+}
+
+Node instproc install_pvc_database {} {
+    $self instvar classifier_
+    set pvc_database [new pvc_db]
+    $classifier_ cmd configure_atmswitch $pvc_database
+
+    return $pvc_database
+}
+
+
+AtmScheduler instproc attach-traces {src dst file {op ""}} {
+	#Do nothing here
+}
+
+
+AtmScheduler instproc attach-nam-traces {src dst file} {
+    
+	#valid only if the default trace type in attach-traces is Drop, Enque, Deque.
+	#see comment above.
+	#this function should be different for different queue when needed.
+	
+	$self attach-traces $src $dst $file "nam"
+}
+
+# helper function for atmconditioner
+SimpleLink instproc get-target {} {
+    $self instvar link_
+    set tg [$link_ target]
+    return $tg
+}
+
+# helper function for atmconditioner
+SimpleLink instproc set-target {tg} {
+    $self instvar link_
+    $link_ target $tg
+}
+
+
+# insert the conditioner between the end-station and the
+# ATMNode.
+
+Simulator instproc atmconditioner {cond n1 atmn pvc_dbase bucketrate qlen} {
+
+
+    $self instvar link_
+    set sid [$n1 id]
+    set did [$atmn id]
+    set temp $link_($sid:$did)
+
+    # The conditioner encompasses two modules, the CAC, UPC module and
+    # the traffic shaper (token bucket) module.  Therefore the
+    # linktarget is preceeded by two other modules, the AtmConditioner
+    # and the TBF (token bucket shaper) module.
+
+    $n1 instvar tbf_
+    for {set i 0} {$i < 1} {incr i} {
+       set tbf($i) [new TBF]
+       $tbf($i) set qlen_ $qlen
+       $n1 set tbf_($i) $tbf($i)
+    }
+
+    set tbfrate [$self bw_parse $bucketrate]
+
+    $tbf(0) set rate_ $tbfrate 
+#    $tbf(1) set rate_ $tbfrate
+
+
+    set linktarget [$temp get-target]
+    $temp set-target $cond
+#    $cond target $linktarget
+    $cond target $tbf(0)
+    $tbf(0) target $linktarget
+
+    $atmn instvar classifier_
+    $classifier_ cmd is_atmswitch
+
+# this is to make future reference to the conditioner available 
+    $cond add-pvc_dbase $pvc_dbase
+    set bw [$self bw_parse $bucketrate]
+
+#    $cond total_service_rate_ $bw
+
+    $pvc_dbase attach-conditioner $cond
+
+}
+
+
+#attaching the aal_driver in between agent and classifier
+
+Simulator instproc merge_source_sardriver {source_agent source dest pvc_dbase bw_ dly} {
+    
+    $source instvar sar_
+    $sar_ configure_atmswitch $pvc_dbase
+    
+    set agenttarget [$source_agent target]
+    
+    $source_agent target $sar_
+    $sar_ target $agenttarget 
+    
+    # set the bandwidth and the delay required for scheduling the packets on SAR
+    
+    $sar_ start_timer [$self delay_parse $dly] [$self bw_parse $bw_]
+    
+    return $pvc_dbase
+
+} 
+
+# adding an ATM virtual connection between an end-station and 
+# the ATM Switch
+
+Node instproc add-pvc { vpi vci rxtp txtp type } {
+    
+    $self instvar sar_
+    $self instvar classifier_
+    $classifier_ cmd attach_aal5 $vpi $vci $rxtp $txtp $type
+   
+    set sar_ [new Agent/SARDriver]
+    $sar_ attach_aal5 $vpi $vci $rxtp $txtp $type
+    
+}
+
+
+
+# attaching the destination agent through SAR
+
+Simulator instproc attach-agent-thro-sar { dest_node dest_agent source_agent} {
+
+    $dest_node instvar sar_
+
+    $self attach-agent $dest_node $sar_
+
+    $self connect $source_agent $sar_
+    $self connect $sar_ $dest_agent
+
+}
+
+
+Simulator instproc add_edge_sardriver {edge sar_e pvc_dbase bw_ dly} {
+    
+    $sar_e instvar sar_
+    $sar_ configure_atmswitch $pvc_dbase
+
+    $self instvar link_
+    set sid [$edge id]
+    set did [$sar_e id]
+    set temp $link_($sid:$did)
+    set linktarget [$temp get-target]
+
+    $temp set-target $sar_
+    $sar_ target $linktarget
+
+    # set the bandwidth and the delay required for scheduling the packets on SAR
+    
+    $sar_ start_timer [$self delay_parse $dly] [$self bw_parse $bw_]
+    
+    return $pvc_dbase
+
+} 
+
diff -urN ns-2.1b9/tcl/lib/ns-lib.tcl ns-allinone-2.1b9/ns-2.1b9/tcl/lib/ns-lib.tcl
--- ns-2.1b9/tcl/lib/ns-lib.tcl	Sat Mar 30 15:08:54 2002
+++ ns-allinone-2.1b9/ns-2.1b9/tcl/lib/ns-lib.tcl	Fri Jul 12 15:07:47 2002
@@ -207,6 +207,9 @@
 # PGM
 source ../pgm/ns-pgm.tcl
 
+#ATM, CNRG, UNH
+source ns-atm.tcl
+
 # Obsolete modules
 #source ns-wireless-mip.tcl
 #source ns-nam.tcl
diff -urN ns-2.1b9/tcl/lib/ns-packet.tcl ns-allinone-2.1b9/ns-2.1b9/tcl/lib/ns-packet.tcl
--- ns-2.1b9/tcl/lib/ns-packet.tcl	Mon Jan 14 16:02:34 2002
+++ ns-allinone-2.1b9/ns-2.1b9/tcl/lib/ns-packet.tcl	Fri Jul 12 15:07:42 2002
@@ -155,6 +155,8 @@
 	UMP 
 	Pushback
 	NV
+# ATM extension, CNRG, UNH
+	ATM
 } {
 	add-packet-header $prot
 }
diff -urN ns-2.1b9/trace/trace.cc ns-allinone-2.1b9/ns-2.1b9/trace/trace.cc
--- ns-2.1b9/trace/trace.cc	Sat Apr 13 16:14:00 2002
+++ ns-allinone-2.1b9/ns-2.1b9/trace/trace.cc	Fri Jul 12 15:06:41 2002
@@ -34,6 +34,10 @@
  * @(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/trace/trace.cc,v 1.75 2002/04/13 20:14:00 buchheim Exp $ (LBL)
  */
 
+/* ********************************************************************* *
+ *   THE ATM PORT FOR THIS FILE IS COMPLETED                             *
+ * ********************************************************************* */
+
 #include <stdio.h>
 #include <stdlib.h>
 #include "packet.h"
@@ -47,6 +51,8 @@
 #include "trace.h"
 #include "rap/rap.h"
 
+//ATM extension, CNRG, UNH
+#include "atm/atm.h"
 
 //const double Trace::PRECISION = 1.0e+6; 
 
@@ -218,6 +224,14 @@
 	hdr_tcp *tcph = hdr_tcp::access(p);
 	hdr_srm *sh = hdr_srm::access(p); 
 
+	//ATM EXTN, CNRG, UNH
+	hdr_atm *atmh = hdr_atm::access(p);
+        hdr_cmn *atm_th;
+
+	if (p->is_atm())
+		atm_th = hdr_cmn::access(atmh->packet);
+
+
 	const char* sname = "null";
 
 	packet_t t = th->ptype();
@@ -280,7 +294,7 @@
 			dst_nodeaddr,
 			dst_portaddr,
 			seqno,flags,sname);
-	} else if (!show_tcphdr_) {
+	} else if ((!show_tcphdr_) && (!(p->is_atm()))) {             // CNRG ATM extn
 		sprintf(pt_->buffer(), "%c "TIME_FORMAT" %d %d %s %d %s %d %s.%s %s.%s %d %d",
 			tt,
 			pt_->round(Scheduler::instance().clock()),
@@ -300,6 +314,30 @@
 			dst_portaddr,
 			seqno,
 			th->uid() /* was p->uid_ */);
+
+		/* ******************* *
+		 * ATM extn, CNRG, UNH *
+		 * ******************* */
+	} else if (p->is_atm()) {
+		sprintf(pt_->buffer(), "%c "TIME_FORMAT" %d %d %s %d %s %d %s.%s %s.%s %d %d %d %d.%d",
+			tt,
+			pt_->round(Scheduler::instance().clock()),
+			s,
+			d,
+			name,
+			th->size(),
+			flags,
+			iph->flowid() /* was p->class_ */,
+			src_nodeaddr,
+			src_portaddr,
+                        dst_nodeaddr,
+			dst_portaddr,
+			seqno,
+                        atm_th->uid(),
+			th->uid(), /* this is atm packet uid_ */
+			atmh->vpi,
+			atmh->vci);
+
 	} else {
 		sprintf(pt_->buffer(), 
 			"%c "TIME_FORMAT" %d %d %s %d %s %d %s.%s %s.%s %d %d %d 0x%x %d %d",
