merge
authorNicola Baldo <nbaldo@cttc.es>
Fri, 16 Dec 2011 18:51:18 +0100
changeset 7830 c462e6fad794
parent 7829 30080a27a039 (current diff)
parent 7641 c6854419e3db (diff)
child 7831 6cf69d27f292
merge
--- a/.hgignore	Fri Dec 16 18:50:05 2011 +0100
+++ b/.hgignore	Fri Dec 16 18:51:18 2011 +0100
@@ -7,6 +7,7 @@
 ^testpy-output
 ^doc/html
 ^doc/latex
+^doc/ns3-object.txt
 ^\.lock-wafbuild
 ^\.waf
 ^doc/introspected-doxygen\.h$
--- a/README	Fri Dec 16 18:50:05 2011 +0100
+++ b/README	Fri Dec 16 18:51:18 2011 +0100
@@ -24,14 +24,15 @@
 will be contributed by the community in an open collaboration
 process.
 
-Contributing to the ns-3 project is still a very informal
-process because that process depends heavily on the background
-of the people involved, the amount of time they can invest
-and the type of model they want to work on.  
+The process of contributing to the ns-3 project varies with
+the people involved, the amount of time they can invest
+and the type of model they want to work on, but the current
+process that the project tries to follow is described here:
+http://www.nsnam.org/developers/contributing-code/
 
-Despite this lack of a formal process, there are a number of 
-steps which naturally stem from the open-source roots of the
-project.  These steps are described in doc/contributing.txt
+This README excerpts some details from a more extensive
+tutorial that is maintained at:
+http://www.nsnam.org/documentation/latest/
 
 2) Building ns-3
 ----------------
@@ -47,9 +48,13 @@
 included in the file doc/build.txt
 
 However, the real quick and dirty way to get started is to
-type the command "./waf configure; ./waf" the the directory which contains
+type the command
+  ./waf configure --enable-examples
+followed by
+  ./waf 
+in the the directory which contains
 this README file. The files built will be copied in the
-build/debug or build/optimized.
+build/ directory.
 
 The current codebase is expected to build and run on the
 set of platforms listed in the RELEASE_NOTES file.
@@ -60,15 +65,16 @@
 3) Running ns-3
 ---------------
 
-On recent Linux systems, once you have built ns-3, it 
-should be easy to run the sample programs with the
-following command:
+On recent Linux systems, once you have built ns-3 (with examples
+enabled), it should be easy to run the sample programs with the
+following command, such as:
 
-./waf --run simple-global-routing
+  ./waf --run simple-global-routing
 
 That program should generate a simple-global-routing.tr text 
 trace file and a set of simple-global-routing-xx-xx.pcap binary
 pcap trace files, which can be read by tcpdump -tt -r filename.pcap
+The program source can be found in the examples/routing directory.
 
 4) Getting access to the ns-3 documentation
 -------------------------------------------
@@ -79,18 +85,19 @@
 some ns-3 documentation. 
 
 All of that documentation should always be available from
-the ns-3 website: http:://www.nsnam.org/ but we
-include some of it in this release for ease of use.
+the ns-3 website: http:://www.nsnam.org/documentation/.
 
 This documentation includes:
 
   - a tutorial
  
-  - a manual
+  - a reference manual
+
+  - models in the ns-3 model library
 
   - a wiki for user-contributed tips: http://www.nsnam.org/wiki/
 
-  - an API documentation generated using doxygen: this is
+  - API documentation generated using doxygen: this is
     a reference manual, most likely not very well suited 
     as introductory text:
     http://www.nsnam.org/doxygen/index.html
--- a/RELEASE_NOTES	Fri Dec 16 18:50:05 2011 +0100
+++ b/RELEASE_NOTES	Fri Dec 16 18:51:18 2011 +0100
@@ -18,12 +18,61 @@
 
 Bugs fixed
 ----------
+ - bug 962 - list of paths to reach objects contains bogus entries
+ - bug 1001 - Buffer::CopyData() doesn't return the number of bytes copied
+ - bug 1010 - Uan model sleep patch
+ - bug 1020 - Wrong usage of the originator sequence number in HWMP PREP
+ - bug 1021 - Beacon collision avoidance in Mesh module works incorrectly
+ - bug 1039 - Nagle's algorithm in TCP 
+ - bug 1055 - Wrong UAN's Thorp absorption loss model formula
+ - bug 1059 - Unable to load trace files created from SUMO and TraNS Lite
+ - bug 1112 - Advance m_nextTxSequence upon retransmit after RTO 
+ - bug 1137 - mpi module is hard-coded for openmpi
+ - bug 1166 - IPV4 TCP failed to send a RST when connect arrives before listen
+ - bug 1186 - Ipv4Header lacks DSCP and ECN
+ - bug 1204 - Can't Parse Time +100000000.0ns
+ - bug 1219 - Coding style of ns2-mobility-helper-test-suite.cc is fixed
+ - bug 1257 - waf install __init__ Python files even with --disable-python
+ - bug 1263 - waf configure fails on FreeBSD 9.0-BETA2 amd64
+ - bug 1266 - gdb cannot be loaded
+ - bug 1227 - Spurious RTO due to low min RTO
+ - bug 1229 - Multiplication overflow in WaypointMobilityModel::EndMobility
+ - bug 1242 - m_lastRtt in tcp-socket-base.cc not implemented
+ - bug 1256 - TCP unnecessary snd.nxt advance
+ - bug 1265 - Make ns-3 directory "movable"
+ - bug 1269 - sqlite3 not found on FreeBSD
+ - bug 1270 - "Checking boost includes" weirdness
+ - bug 1278 - Ipv4ClickRouting::HandleScheduleFromClick bug
+ - bug 1281 - Checksum not calculated when doing IP fragmentation
+ - bug 1285 - IPv6 Localhost is marked as GLOBAL instead of HOST
+ - bug 1290 - buffer-test.cc gets a valgrind error
+ - bug 1295 - Missing const qualifiers in TopologyRead 
+ - bug 1299 - EnableAsciiIpv4All tracing doesn't show transmitted/recvd packets
+ - bug 1300 - HalfDuplexIdealPhy notify SpectrumInterference of AbortRx 
+ - bug 1301 - Ns2MobilityHelper causes Node GetPosition() to return NaN
+ - bug 1305 - do not list modules built upon exiting waf shell
+ - bug 1312: TopologyRead Assert condition fix
+ - IPv4 packets double fragmentation was broken 
+ - Fix wifi-clear-channel-cmu.cc example
+ - NetAnim: fix for bcast packet reuse
+ - Missing PropagationLossModel.CalcRxPower in Python bindings
+ - Corrected compilation behavior in Ubuntu 11.10 due to ldd behavior change
+ - Added required PTHREAD dependency to RT library check.
 
 Supported platforms
 -------------------
+ns-3.13 has been tested on the following platforms.  Not all features are
+available on all platforms; check the Installation page on the project wiki.
+
+- Ubuntu 11.04 (32/64 bit) with g++-4.5.2 
+- Ubuntu 10.04.3 LTS (64 bit) with g++-4.4.3, g++-3.4.6 
+- OS X Lion with g++-4.2.1
+- OS X Snow Leopard with g++-4.2.1 
+- Fedora Core 14 (64 bit) with g++-4.5.1
 
 New user-visible features
 -------------------------
+- IPv6 address generator
 
 Known issues
 ------------
--- a/doc/build.txt	Fri Dec 16 18:50:05 2011 +0100
+++ b/doc/build.txt	Fri Dec 16 18:51:18 2011 +0100
@@ -23,28 +23,28 @@
 
 To see valid configure options, type ./waf --help.  The most important
 option is -d <debug level>.  Valid debug levels (which are listed in
-waf --help) are: "debug" or "optimized".  It is
+waf --help) are: "debug" or "optimized", with debug being default.  It is
 also possible to change the flags used for compilation with (e.g.):
-CXXFLAGS="-O3" ./waf configure.
+CXXFLAGS="-O3" ./waf configure.  By default, ns-3 is built as debug code, 
+with examples and tests disabled, and with python bindings enabled.  
 
 [ Note:  Unlike some other build tools, to change the build target,
 the option must be supplied during the configure stage rather than
 the build stage (i.e., "./waf -d optimized" will not work; instead, do
 "./waf -d optimized configure; ./waf" ]
 
-The resulting binaries are placed in build/<debuglevel>/srcpath.
+The resulting executables and libraries are placed in build/.
 
 Other waf usages include:
 
  1. ./waf configure --enable-examples --enable-tests
     Turn on examples and tests.
 
- 2. ./waf --doxygen
-    Run doxygen to generate documentation
+ 2. ./waf configure --disable-python
+    Disable python bindings.
 
- 3. ./waf --lcov-report
-    Run code coverage analysis (assuming the project was configured
-with --enable-gcov)
+ 3. ./waf --doxygen
+    Run doxygen to generate documentation
 
  4. ./waf --run "program [args]"
     Run a ns3 program, given its target name, with the given
@@ -79,29 +79,29 @@
   1. Create the module directory under src;
   2. Add the source files to it;
   3. Add a 'wscript' describing it;
-  4. Add the module subdirectory name to the all_modules list in src/wscript.
+
+A convenience program to auto-generate the template of a new module can
+be found in src/create-module.py.
 
 A module's wscript file is basically a regular Waf script.  A ns-3
 module is created as a cpp/shlib object, like this:
 
 def build(bld):
-    obj = bld.create_obj('cpp', 'shlib')
-
-    ## set module name; by convention it starts with ns3-
-    obj.name = 'ns3-mymodule'
-    obj.target = obj.name 
-
-    ## list dependencies to other modules
-    obj.uselib_local = ['ns3-core'] 
+    module = bld.create_ns3_module('ns3-mymodule', ['core'])
+    module.source = [
+        'model/ns3-mymodule.cc',
+        'helper/ns3-mymodule-helper.cc',
+        ]
 
-    ## list source files (private or public header files excluded)
-    obj.source = [
-        'mymodule.cc',
-    ]
+    headers = bld.new_task_gen(features=['ns3header'])
+    headers.module = 'ns3-mymodule'
+    headers.source = [
+        'model/ns3-mymodule.h',
+        'helper/ns3-mymodule-helper.h',
+        ]
 
-    ## list module public header files
-    headers = bld.create_obj('ns3header')
-    headers.source = [
-        'mymodule-header.h',
-    ]
+    if bld.env.ENABLE_EXAMPLES:
+        bld.add_subdirs('examples')
 
+    # bld.ns3_python_bindings()
+
--- a/doc/doxygen.conf	Fri Dec 16 18:50:05 2011 +0100
+++ b/doc/doxygen.conf	Fri Dec 16 18:51:18 2011 +0100
@@ -25,7 +25,7 @@
 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded
 # by quotes) that should identify the project.
 
-PROJECT_NAME           = "NS-3 "
+PROJECT_NAME           = "ns-3 "
 
 # The PROJECT_NUMBER tag can be used to enter a project or revision number.
 # This could be handy for archiving the generated documentation or
@@ -590,8 +590,7 @@
 # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
 
 FILE_PATTERNS          = *.h \
-                         *.tcc \
-                         node-list.cc
+                         *.cc
 
 # The RECURSIVE tag can be used to turn specify whether or not subdirectories
 # should be searched for input files as well. Possible values are YES and NO.
@@ -603,11 +602,7 @@
 # excluded from the INPUT source files. This way you can easily exclude a
 # subdirectory from a directory tree whose root is specified with the INPUT tag.
 
-EXCLUDE                = src/olsr/model/olsr-state.h \
-                         src/olsr/model/olsr-repositories.h \
-                         src/core/model/high-precision.h \
-                         src/core/model/high-precision-128.h \
-                         src/core/model/high-precision-double.h
+EXCLUDE                =
 
 # The EXCLUDE_SYMLINKS tag can be used select whether or not files or
 # directories that are symbolic links (a Unix filesystem feature) are excluded
@@ -635,7 +630,39 @@
 # directories that contain example code fragments that are included (see
 # the \include command).
 
-EXAMPLE_PATH           = 
+EXAMPLE_PATH           = src/aodv/examples \
+                         src/bridge/examples \
+                         src/click/examples \
+                         src/config-store/examples \
+                         src/core/examples \
+                         src/csma/examples \
+                         src/csma-layout/examples \
+                         src/dsdv/examples \
+                         src/emu/examples \
+                         src/energy/examples \
+                         src/flow-monitor/examples \
+                         src/internet/examples \
+                         src/lte/examples \
+                         src/mesh/examples \
+                         src/mobility/examples \
+                         src/mpi/examples \
+                         src/netanim/examples \
+                         src/network/examples \
+                         src/nix-vector-routing/examples \
+                         src/olsr/examples \
+                         src/openflow/examples \
+                         src/point-to-point/examples \
+                         src/propagation/examples \
+                         src/spectrum/examples \
+                         src/tap-bridge/examples \
+                         src/template/examples \
+                         src/tools/examples \
+                         src/topology-read/examples \
+                         src/uan/examples \
+                         src/virtual-net-device/examples \
+                         src/visualizer/examples \
+                         src/wifi/examples \
+                         src/wimax/examples
 
 # If the value of the EXAMPLE_PATH tag contains directories, you can use the
 # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
--- a/examples/wireless/wifi-clear-channel-cmu.cc	Fri Dec 16 18:50:05 2011 +0100
+++ b/examples/wireless/wifi-clear-channel-cmu.cc	Fri Dec 16 18:51:18 2011 +0100
@@ -150,6 +150,7 @@
   TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
   Ptr<Socket> source = Socket::CreateSocket (c.Get (1), tid);
   InetSocketAddress remote = InetSocketAddress (Ipv4Address ("255.255.255.255"), 80);
+  source->SetAllowBroadcast (true);
   source->Connect (remote);
   uint32_t packetSize = 1014;
   uint32_t maxPacketCount = 200;
@@ -212,6 +213,7 @@
           wifiPhy.Set ("EnergyDetectionThreshold", DoubleValue (-110.0) );
           wifiPhy.Set ("CcaMode1Threshold", DoubleValue (-110.0) );
           wifiPhy.Set ("TxPowerStart", DoubleValue (15.0) );
+          wifiPhy.Set ("TxPowerEnd", DoubleValue (15.0) );
           wifiPhy.Set ("RxGain", DoubleValue (0) );
           wifiPhy.Set ("RxNoiseFigure", DoubleValue (7) );
           uint32_t pktsRecvd = experiment.Run (wifi, wifiPhy, wifiMac, wifiChannel);
Binary file src/aodv/test/tcp-chain-test-0-0.pcap has changed
Binary file src/aodv/test/tcp-chain-test-9-0.pcap has changed
--- a/src/applications/bindings/modulegen__gcc_ILP32.py	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/applications/bindings/modulegen__gcc_ILP32.py	Fri Dec 16 18:51:18 2011 +0100
@@ -242,6 +242,14 @@
     module.add_enum('', ['FRAME_FLAG_NONE', 'FRAME_FLAG_CFP', 'FRAME_FLAG_SHORT_PREAMBLE', 'FRAME_FLAG_WEP', 'FRAME_FLAG_FRAGMENTED', 'FRAME_FLAG_FCS_INCLUDED', 'FRAME_FLAG_DATA_PADDING', 'FRAME_FLAG_BAD_FCS', 'FRAME_FLAG_SHORT_GUARD'], outer_class=root_module['ns3::RadiotapHeader'], import_from_module='ns.network')
     ## radiotap-header.h (module 'network'): ns3::RadiotapHeader [enumeration]
     module.add_enum('', ['CHANNEL_FLAG_NONE', 'CHANNEL_FLAG_TURBO', 'CHANNEL_FLAG_CCK', 'CHANNEL_FLAG_OFDM', 'CHANNEL_FLAG_SPECTRUM_2GHZ', 'CHANNEL_FLAG_SPECTRUM_5GHZ', 'CHANNEL_FLAG_PASSIVE', 'CHANNEL_FLAG_DYNAMIC', 'CHANNEL_FLAG_GFSK'], outer_class=root_module['ns3::RadiotapHeader'], import_from_module='ns.network')
+    ## red-queue.h (module 'network'): ns3::RedQueue [class]
+    module.add_class('RedQueue', import_from_module='ns.network', parent=root_module['ns3::Queue'])
+    ## red-queue.h (module 'network'): ns3::RedQueue [enumeration]
+    module.add_enum('', ['DTYPE_NONE', 'DTYPE_FORCED', 'DTYPE_UNFORCED'], outer_class=root_module['ns3::RedQueue'], import_from_module='ns.network')
+    ## red-queue.h (module 'network'): ns3::RedQueue::Mode [enumeration]
+    module.add_enum('Mode', ['ILLEGAL', 'PACKETS', 'BYTES'], outer_class=root_module['ns3::RedQueue'], import_from_module='ns.network')
+    ## red-queue.h (module 'network'): ns3::RedQueue::Stats [struct]
+    module.add_class('Stats', import_from_module='ns.network', outer_class=root_module['ns3::RedQueue'])
     ## seq-ts-header.h (module 'applications'): ns3::SeqTsHeader [class]
     module.add_class('SeqTsHeader', parent=root_module['ns3::Header'])
     ## simple-ref-count.h (module 'core'): ns3::SimpleRefCount<ns3::AttributeAccessor, ns3::empty, ns3::DefaultDeleter<ns3::AttributeAccessor> > [class]
@@ -306,6 +314,10 @@
     module.add_class('AttributeChecker', allow_subclassing=False, automatic_type_narrowing=True, import_from_module='ns.core', parent=root_module['ns3::SimpleRefCount< ns3::AttributeChecker, ns3::empty, ns3::DefaultDeleter<ns3::AttributeChecker> >'])
     ## attribute.h (module 'core'): ns3::AttributeValue [class]
     module.add_class('AttributeValue', allow_subclassing=False, automatic_type_narrowing=True, import_from_module='ns.core', parent=root_module['ns3::SimpleRefCount< ns3::AttributeValue, ns3::empty, ns3::DefaultDeleter<ns3::AttributeValue> >'])
+    ## boolean.h (module 'core'): ns3::BooleanChecker [class]
+    module.add_class('BooleanChecker', import_from_module='ns.core', parent=root_module['ns3::AttributeChecker'])
+    ## boolean.h (module 'core'): ns3::BooleanValue [class]
+    module.add_class('BooleanValue', import_from_module='ns.core', parent=root_module['ns3::AttributeValue'])
     ## bulk-send-application.h (module 'applications'): ns3::BulkSendApplication [class]
     module.add_class('BulkSendApplication', parent=root_module['ns3::Application'])
     ## callback.h (module 'core'): ns3::CallbackChecker [class]
@@ -585,6 +597,8 @@
     register_Ns3PcapFileWrapper_methods(root_module, root_module['ns3::PcapFileWrapper'])
     register_Ns3Queue_methods(root_module, root_module['ns3::Queue'])
     register_Ns3RadiotapHeader_methods(root_module, root_module['ns3::RadiotapHeader'])
+    register_Ns3RedQueue_methods(root_module, root_module['ns3::RedQueue'])
+    register_Ns3RedQueueStats_methods(root_module, root_module['ns3::RedQueue::Stats'])
     register_Ns3SeqTsHeader_methods(root_module, root_module['ns3::SeqTsHeader'])
     register_Ns3SimpleRefCount__Ns3AttributeAccessor_Ns3Empty_Ns3DefaultDeleter__lt__ns3AttributeAccessor__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::AttributeAccessor, ns3::empty, ns3::DefaultDeleter<ns3::AttributeAccessor> >'])
     register_Ns3SimpleRefCount__Ns3AttributeChecker_Ns3Empty_Ns3DefaultDeleter__lt__ns3AttributeChecker__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::AttributeChecker, ns3::empty, ns3::DefaultDeleter<ns3::AttributeChecker> >'])
@@ -613,6 +627,8 @@
     register_Ns3AttributeAccessor_methods(root_module, root_module['ns3::AttributeAccessor'])
     register_Ns3AttributeChecker_methods(root_module, root_module['ns3::AttributeChecker'])
     register_Ns3AttributeValue_methods(root_module, root_module['ns3::AttributeValue'])
+    register_Ns3BooleanChecker_methods(root_module, root_module['ns3::BooleanChecker'])
+    register_Ns3BooleanValue_methods(root_module, root_module['ns3::BooleanValue'])
     register_Ns3BulkSendApplication_methods(root_module, root_module['ns3::BulkSendApplication'])
     register_Ns3CallbackChecker_methods(root_module, root_module['ns3::CallbackChecker'])
     register_Ns3CallbackImplBase_methods(root_module, root_module['ns3::CallbackImplBase'])
@@ -4504,6 +4520,70 @@
                    [param('uint64_t', 'tsft')])
     return
 
+def register_Ns3RedQueue_methods(root_module, cls):
+    ## red-queue.h (module 'network'): ns3::RedQueue::RedQueue(ns3::RedQueue const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::RedQueue const &', 'arg0')])
+    ## red-queue.h (module 'network'): ns3::RedQueue::RedQueue() [constructor]
+    cls.add_constructor([])
+    ## red-queue.h (module 'network'): ns3::RedQueue::Mode ns3::RedQueue::GetMode() [member function]
+    cls.add_method('GetMode', 
+                   'ns3::RedQueue::Mode', 
+                   [])
+    ## red-queue.h (module 'network'): uint32_t ns3::RedQueue::GetQueueSize() [member function]
+    cls.add_method('GetQueueSize', 
+                   'uint32_t', 
+                   [])
+    ## red-queue.h (module 'network'): ns3::RedQueue::Stats ns3::RedQueue::GetStats() [member function]
+    cls.add_method('GetStats', 
+                   'ns3::RedQueue::Stats', 
+                   [])
+    ## red-queue.h (module 'network'): static ns3::TypeId ns3::RedQueue::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## red-queue.h (module 'network'): void ns3::RedQueue::SetMode(ns3::RedQueue::Mode mode) [member function]
+    cls.add_method('SetMode', 
+                   'void', 
+                   [param('ns3::RedQueue::Mode', 'mode')])
+    ## red-queue.h (module 'network'): void ns3::RedQueue::SetQueueLimit(uint32_t lim) [member function]
+    cls.add_method('SetQueueLimit', 
+                   'void', 
+                   [param('uint32_t', 'lim')])
+    ## red-queue.h (module 'network'): void ns3::RedQueue::SetTh(double minTh, double maxTh) [member function]
+    cls.add_method('SetTh', 
+                   'void', 
+                   [param('double', 'minTh'), param('double', 'maxTh')])
+    ## red-queue.h (module 'network'): ns3::Ptr<ns3::Packet> ns3::RedQueue::DoDequeue() [member function]
+    cls.add_method('DoDequeue', 
+                   'ns3::Ptr< ns3::Packet >', 
+                   [], 
+                   visibility='private', is_virtual=True)
+    ## red-queue.h (module 'network'): bool ns3::RedQueue::DoEnqueue(ns3::Ptr<ns3::Packet> p) [member function]
+    cls.add_method('DoEnqueue', 
+                   'bool', 
+                   [param('ns3::Ptr< ns3::Packet >', 'p')], 
+                   visibility='private', is_virtual=True)
+    ## red-queue.h (module 'network'): ns3::Ptr<const ns3::Packet> ns3::RedQueue::DoPeek() const [member function]
+    cls.add_method('DoPeek', 
+                   'ns3::Ptr< ns3::Packet const >', 
+                   [], 
+                   is_const=True, visibility='private', is_virtual=True)
+    return
+
+def register_Ns3RedQueueStats_methods(root_module, cls):
+    ## red-queue.h (module 'network'): ns3::RedQueue::Stats::Stats() [constructor]
+    cls.add_constructor([])
+    ## red-queue.h (module 'network'): ns3::RedQueue::Stats::Stats(ns3::RedQueue::Stats const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::RedQueue::Stats const &', 'arg0')])
+    ## red-queue.h (module 'network'): ns3::RedQueue::Stats::forcedDrop [variable]
+    cls.add_instance_attribute('forcedDrop', 'uint32_t', is_const=False)
+    ## red-queue.h (module 'network'): ns3::RedQueue::Stats::qLimDrop [variable]
+    cls.add_instance_attribute('qLimDrop', 'uint32_t', is_const=False)
+    ## red-queue.h (module 'network'): ns3::RedQueue::Stats::unforcedDrop [variable]
+    cls.add_instance_attribute('unforcedDrop', 'uint32_t', is_const=False)
+    return
+
 def register_Ns3SeqTsHeader_methods(root_module, cls):
     ## seq-ts-header.h (module 'applications'): ns3::SeqTsHeader::SeqTsHeader(ns3::SeqTsHeader const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::SeqTsHeader const &', 'arg0')])
@@ -5472,6 +5552,47 @@
                    is_pure_virtual=True, is_const=True, is_virtual=True)
     return
 
+def register_Ns3BooleanChecker_methods(root_module, cls):
+    ## boolean.h (module 'core'): ns3::BooleanChecker::BooleanChecker() [constructor]
+    cls.add_constructor([])
+    ## boolean.h (module 'core'): ns3::BooleanChecker::BooleanChecker(ns3::BooleanChecker const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::BooleanChecker const &', 'arg0')])
+    return
+
+def register_Ns3BooleanValue_methods(root_module, cls):
+    cls.add_output_stream_operator()
+    ## boolean.h (module 'core'): ns3::BooleanValue::BooleanValue(ns3::BooleanValue const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::BooleanValue const &', 'arg0')])
+    ## boolean.h (module 'core'): ns3::BooleanValue::BooleanValue() [constructor]
+    cls.add_constructor([])
+    ## boolean.h (module 'core'): ns3::BooleanValue::BooleanValue(bool value) [constructor]
+    cls.add_constructor([param('bool', 'value')])
+    ## boolean.h (module 'core'): ns3::Ptr<ns3::AttributeValue> ns3::BooleanValue::Copy() const [member function]
+    cls.add_method('Copy', 
+                   'ns3::Ptr< ns3::AttributeValue >', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## boolean.h (module 'core'): bool ns3::BooleanValue::DeserializeFromString(std::string value, ns3::Ptr<ns3::AttributeChecker const> checker) [member function]
+    cls.add_method('DeserializeFromString', 
+                   'bool', 
+                   [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], 
+                   is_virtual=True)
+    ## boolean.h (module 'core'): bool ns3::BooleanValue::Get() const [member function]
+    cls.add_method('Get', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## boolean.h (module 'core'): std::string ns3::BooleanValue::SerializeToString(ns3::Ptr<ns3::AttributeChecker const> checker) const [member function]
+    cls.add_method('SerializeToString', 
+                   'std::string', 
+                   [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], 
+                   is_const=True, is_virtual=True)
+    ## boolean.h (module 'core'): void ns3::BooleanValue::Set(bool value) [member function]
+    cls.add_method('Set', 
+                   'void', 
+                   [param('bool', 'value')])
+    return
+
 def register_Ns3BulkSendApplication_methods(root_module, cls):
     ## bulk-send-application.h (module 'applications'): ns3::BulkSendApplication::BulkSendApplication(ns3::BulkSendApplication const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::BulkSendApplication const &', 'arg0')])
--- a/src/applications/bindings/modulegen__gcc_LP64.py	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/applications/bindings/modulegen__gcc_LP64.py	Fri Dec 16 18:51:18 2011 +0100
@@ -242,6 +242,14 @@
     module.add_enum('', ['FRAME_FLAG_NONE', 'FRAME_FLAG_CFP', 'FRAME_FLAG_SHORT_PREAMBLE', 'FRAME_FLAG_WEP', 'FRAME_FLAG_FRAGMENTED', 'FRAME_FLAG_FCS_INCLUDED', 'FRAME_FLAG_DATA_PADDING', 'FRAME_FLAG_BAD_FCS', 'FRAME_FLAG_SHORT_GUARD'], outer_class=root_module['ns3::RadiotapHeader'], import_from_module='ns.network')
     ## radiotap-header.h (module 'network'): ns3::RadiotapHeader [enumeration]
     module.add_enum('', ['CHANNEL_FLAG_NONE', 'CHANNEL_FLAG_TURBO', 'CHANNEL_FLAG_CCK', 'CHANNEL_FLAG_OFDM', 'CHANNEL_FLAG_SPECTRUM_2GHZ', 'CHANNEL_FLAG_SPECTRUM_5GHZ', 'CHANNEL_FLAG_PASSIVE', 'CHANNEL_FLAG_DYNAMIC', 'CHANNEL_FLAG_GFSK'], outer_class=root_module['ns3::RadiotapHeader'], import_from_module='ns.network')
+    ## red-queue.h (module 'network'): ns3::RedQueue [class]
+    module.add_class('RedQueue', import_from_module='ns.network', parent=root_module['ns3::Queue'])
+    ## red-queue.h (module 'network'): ns3::RedQueue [enumeration]
+    module.add_enum('', ['DTYPE_NONE', 'DTYPE_FORCED', 'DTYPE_UNFORCED'], outer_class=root_module['ns3::RedQueue'], import_from_module='ns.network')
+    ## red-queue.h (module 'network'): ns3::RedQueue::Mode [enumeration]
+    module.add_enum('Mode', ['ILLEGAL', 'PACKETS', 'BYTES'], outer_class=root_module['ns3::RedQueue'], import_from_module='ns.network')
+    ## red-queue.h (module 'network'): ns3::RedQueue::Stats [struct]
+    module.add_class('Stats', import_from_module='ns.network', outer_class=root_module['ns3::RedQueue'])
     ## seq-ts-header.h (module 'applications'): ns3::SeqTsHeader [class]
     module.add_class('SeqTsHeader', parent=root_module['ns3::Header'])
     ## simple-ref-count.h (module 'core'): ns3::SimpleRefCount<ns3::AttributeAccessor, ns3::empty, ns3::DefaultDeleter<ns3::AttributeAccessor> > [class]
@@ -306,6 +314,10 @@
     module.add_class('AttributeChecker', allow_subclassing=False, automatic_type_narrowing=True, import_from_module='ns.core', parent=root_module['ns3::SimpleRefCount< ns3::AttributeChecker, ns3::empty, ns3::DefaultDeleter<ns3::AttributeChecker> >'])
     ## attribute.h (module 'core'): ns3::AttributeValue [class]
     module.add_class('AttributeValue', allow_subclassing=False, automatic_type_narrowing=True, import_from_module='ns.core', parent=root_module['ns3::SimpleRefCount< ns3::AttributeValue, ns3::empty, ns3::DefaultDeleter<ns3::AttributeValue> >'])
+    ## boolean.h (module 'core'): ns3::BooleanChecker [class]
+    module.add_class('BooleanChecker', import_from_module='ns.core', parent=root_module['ns3::AttributeChecker'])
+    ## boolean.h (module 'core'): ns3::BooleanValue [class]
+    module.add_class('BooleanValue', import_from_module='ns.core', parent=root_module['ns3::AttributeValue'])
     ## bulk-send-application.h (module 'applications'): ns3::BulkSendApplication [class]
     module.add_class('BulkSendApplication', parent=root_module['ns3::Application'])
     ## callback.h (module 'core'): ns3::CallbackChecker [class]
@@ -585,6 +597,8 @@
     register_Ns3PcapFileWrapper_methods(root_module, root_module['ns3::PcapFileWrapper'])
     register_Ns3Queue_methods(root_module, root_module['ns3::Queue'])
     register_Ns3RadiotapHeader_methods(root_module, root_module['ns3::RadiotapHeader'])
+    register_Ns3RedQueue_methods(root_module, root_module['ns3::RedQueue'])
+    register_Ns3RedQueueStats_methods(root_module, root_module['ns3::RedQueue::Stats'])
     register_Ns3SeqTsHeader_methods(root_module, root_module['ns3::SeqTsHeader'])
     register_Ns3SimpleRefCount__Ns3AttributeAccessor_Ns3Empty_Ns3DefaultDeleter__lt__ns3AttributeAccessor__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::AttributeAccessor, ns3::empty, ns3::DefaultDeleter<ns3::AttributeAccessor> >'])
     register_Ns3SimpleRefCount__Ns3AttributeChecker_Ns3Empty_Ns3DefaultDeleter__lt__ns3AttributeChecker__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::AttributeChecker, ns3::empty, ns3::DefaultDeleter<ns3::AttributeChecker> >'])
@@ -613,6 +627,8 @@
     register_Ns3AttributeAccessor_methods(root_module, root_module['ns3::AttributeAccessor'])
     register_Ns3AttributeChecker_methods(root_module, root_module['ns3::AttributeChecker'])
     register_Ns3AttributeValue_methods(root_module, root_module['ns3::AttributeValue'])
+    register_Ns3BooleanChecker_methods(root_module, root_module['ns3::BooleanChecker'])
+    register_Ns3BooleanValue_methods(root_module, root_module['ns3::BooleanValue'])
     register_Ns3BulkSendApplication_methods(root_module, root_module['ns3::BulkSendApplication'])
     register_Ns3CallbackChecker_methods(root_module, root_module['ns3::CallbackChecker'])
     register_Ns3CallbackImplBase_methods(root_module, root_module['ns3::CallbackImplBase'])
@@ -4504,6 +4520,70 @@
                    [param('uint64_t', 'tsft')])
     return
 
+def register_Ns3RedQueue_methods(root_module, cls):
+    ## red-queue.h (module 'network'): ns3::RedQueue::RedQueue(ns3::RedQueue const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::RedQueue const &', 'arg0')])
+    ## red-queue.h (module 'network'): ns3::RedQueue::RedQueue() [constructor]
+    cls.add_constructor([])
+    ## red-queue.h (module 'network'): ns3::RedQueue::Mode ns3::RedQueue::GetMode() [member function]
+    cls.add_method('GetMode', 
+                   'ns3::RedQueue::Mode', 
+                   [])
+    ## red-queue.h (module 'network'): uint32_t ns3::RedQueue::GetQueueSize() [member function]
+    cls.add_method('GetQueueSize', 
+                   'uint32_t', 
+                   [])
+    ## red-queue.h (module 'network'): ns3::RedQueue::Stats ns3::RedQueue::GetStats() [member function]
+    cls.add_method('GetStats', 
+                   'ns3::RedQueue::Stats', 
+                   [])
+    ## red-queue.h (module 'network'): static ns3::TypeId ns3::RedQueue::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## red-queue.h (module 'network'): void ns3::RedQueue::SetMode(ns3::RedQueue::Mode mode) [member function]
+    cls.add_method('SetMode', 
+                   'void', 
+                   [param('ns3::RedQueue::Mode', 'mode')])
+    ## red-queue.h (module 'network'): void ns3::RedQueue::SetQueueLimit(uint32_t lim) [member function]
+    cls.add_method('SetQueueLimit', 
+                   'void', 
+                   [param('uint32_t', 'lim')])
+    ## red-queue.h (module 'network'): void ns3::RedQueue::SetTh(double minTh, double maxTh) [member function]
+    cls.add_method('SetTh', 
+                   'void', 
+                   [param('double', 'minTh'), param('double', 'maxTh')])
+    ## red-queue.h (module 'network'): ns3::Ptr<ns3::Packet> ns3::RedQueue::DoDequeue() [member function]
+    cls.add_method('DoDequeue', 
+                   'ns3::Ptr< ns3::Packet >', 
+                   [], 
+                   visibility='private', is_virtual=True)
+    ## red-queue.h (module 'network'): bool ns3::RedQueue::DoEnqueue(ns3::Ptr<ns3::Packet> p) [member function]
+    cls.add_method('DoEnqueue', 
+                   'bool', 
+                   [param('ns3::Ptr< ns3::Packet >', 'p')], 
+                   visibility='private', is_virtual=True)
+    ## red-queue.h (module 'network'): ns3::Ptr<const ns3::Packet> ns3::RedQueue::DoPeek() const [member function]
+    cls.add_method('DoPeek', 
+                   'ns3::Ptr< ns3::Packet const >', 
+                   [], 
+                   is_const=True, visibility='private', is_virtual=True)
+    return
+
+def register_Ns3RedQueueStats_methods(root_module, cls):
+    ## red-queue.h (module 'network'): ns3::RedQueue::Stats::Stats() [constructor]
+    cls.add_constructor([])
+    ## red-queue.h (module 'network'): ns3::RedQueue::Stats::Stats(ns3::RedQueue::Stats const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::RedQueue::Stats const &', 'arg0')])
+    ## red-queue.h (module 'network'): ns3::RedQueue::Stats::forcedDrop [variable]
+    cls.add_instance_attribute('forcedDrop', 'uint32_t', is_const=False)
+    ## red-queue.h (module 'network'): ns3::RedQueue::Stats::qLimDrop [variable]
+    cls.add_instance_attribute('qLimDrop', 'uint32_t', is_const=False)
+    ## red-queue.h (module 'network'): ns3::RedQueue::Stats::unforcedDrop [variable]
+    cls.add_instance_attribute('unforcedDrop', 'uint32_t', is_const=False)
+    return
+
 def register_Ns3SeqTsHeader_methods(root_module, cls):
     ## seq-ts-header.h (module 'applications'): ns3::SeqTsHeader::SeqTsHeader(ns3::SeqTsHeader const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::SeqTsHeader const &', 'arg0')])
@@ -5472,6 +5552,47 @@
                    is_pure_virtual=True, is_const=True, is_virtual=True)
     return
 
+def register_Ns3BooleanChecker_methods(root_module, cls):
+    ## boolean.h (module 'core'): ns3::BooleanChecker::BooleanChecker() [constructor]
+    cls.add_constructor([])
+    ## boolean.h (module 'core'): ns3::BooleanChecker::BooleanChecker(ns3::BooleanChecker const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::BooleanChecker const &', 'arg0')])
+    return
+
+def register_Ns3BooleanValue_methods(root_module, cls):
+    cls.add_output_stream_operator()
+    ## boolean.h (module 'core'): ns3::BooleanValue::BooleanValue(ns3::BooleanValue const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::BooleanValue const &', 'arg0')])
+    ## boolean.h (module 'core'): ns3::BooleanValue::BooleanValue() [constructor]
+    cls.add_constructor([])
+    ## boolean.h (module 'core'): ns3::BooleanValue::BooleanValue(bool value) [constructor]
+    cls.add_constructor([param('bool', 'value')])
+    ## boolean.h (module 'core'): ns3::Ptr<ns3::AttributeValue> ns3::BooleanValue::Copy() const [member function]
+    cls.add_method('Copy', 
+                   'ns3::Ptr< ns3::AttributeValue >', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## boolean.h (module 'core'): bool ns3::BooleanValue::DeserializeFromString(std::string value, ns3::Ptr<ns3::AttributeChecker const> checker) [member function]
+    cls.add_method('DeserializeFromString', 
+                   'bool', 
+                   [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], 
+                   is_virtual=True)
+    ## boolean.h (module 'core'): bool ns3::BooleanValue::Get() const [member function]
+    cls.add_method('Get', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## boolean.h (module 'core'): std::string ns3::BooleanValue::SerializeToString(ns3::Ptr<ns3::AttributeChecker const> checker) const [member function]
+    cls.add_method('SerializeToString', 
+                   'std::string', 
+                   [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], 
+                   is_const=True, is_virtual=True)
+    ## boolean.h (module 'core'): void ns3::BooleanValue::Set(bool value) [member function]
+    cls.add_method('Set', 
+                   'void', 
+                   [param('bool', 'value')])
+    return
+
 def register_Ns3BulkSendApplication_methods(root_module, cls):
     ## bulk-send-application.h (module 'applications'): ns3::BulkSendApplication::BulkSendApplication(ns3::BulkSendApplication const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::BulkSendApplication const &', 'arg0')])
--- a/src/click/wscript	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/click/wscript	Fri Dec 16 18:51:18 2011 +0100
@@ -104,8 +104,8 @@
         ]
 
     if bld.env['NSCLICK'] and bld.env['DL']:
-        module.use      = 'NSCLICK DL'
-        module_test.use = 'NSCLICK DL'
+        module.use.extend(['NSCLICK', 'DL'])
+        module_test.use.extend(['NSCLICK', 'DL'])
 
     headers = bld.new_task_gen(features=['ns3header'])
     headers.module = 'click'
--- a/src/core/model/command-line.h	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/core/model/command-line.h	Fri Dec 16 18:51:18 2011 +0100
@@ -37,9 +37,15 @@
  * CommandLine::AddValue but the most important functionality
  * provided by this class is that it can be used to set the
  * 'initial value' of every attribute in the system with the
- * '\--TypeIdName::AttributeName=value' syntax and it can be used
- * to set the value of every GlobalValue in the system with
- * the \--GlobalValueName=value syntax.
+ * \verbatim
+ *   --TypeIdName::AttributeName=value
+ * \endverbatim
+ * syntax and it can be used to set the value of every GlobalValue
+ * in the system with the
+ * \verbatim
+ *   --GlobalValueName=value
+ * \endverbatim
+ * syntax.
  */
 class CommandLine
 {
--- a/src/core/model/names.cc	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/core/model/names.cc	Fri Dec 16 18:51:18 2011 +0100
@@ -463,8 +463,8 @@
   NameNode *node = &m_root;
 
   //
-  // The string <remaining> is now composed entirely of path segments in the
-  // /Names name space and we have eaten the leading slash. e.g., 
+  // The string <remaining> is now composed entirely of path segments in
+  // the /Names name space and we have eaten the leading slash. e.g., 
   // remaining = "ClientNode/eth0"
   //
   // The start of the search is always at the root of the name space.
--- a/src/core/model/nstime.h	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/core/model/nstime.h	Fri Dec 16 18:51:18 2011 +0100
@@ -359,6 +359,7 @@
   }
   /**
    * \param timeUnit the unit of the value to return
+   * \return int64_t time value
    *
    * Convert the input time into an integer value according to the requested
    * time unit.
@@ -390,6 +391,7 @@
   }
   /**
    * \param timeUnit the unit of the value to return
+   * \return double time value
    *
    * Convert the input time into a floating point value according to the requested
    * time unit.
--- a/src/core/model/test.h	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/core/model/test.h	Fri Dec 16 18:51:18 2011 +0100
@@ -937,7 +937,7 @@
 {
 public:
   /**
-   * \enum TestType
+   * \enum Type
    * \brief Type of test.
    */
   enum Type {
--- a/src/dsdv/bindings/modulegen__gcc_ILP32.py	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/dsdv/bindings/modulegen__gcc_ILP32.py	Fri Dec 16 18:51:18 2011 +0100
@@ -5303,10 +5303,10 @@
     cls.add_constructor([param('ns3::dsdv::RoutingTable const &', 'arg0')])
     ## dsdv-rtable.h (module 'dsdv'): ns3::dsdv::RoutingTable::RoutingTable() [constructor]
     cls.add_constructor([])
-    ## dsdv-rtable.h (module 'dsdv'): bool ns3::dsdv::RoutingTable::AddIpv4Event(ns3::Ipv4Address arg0, ns3::EventId arg1) [member function]
+    ## dsdv-rtable.h (module 'dsdv'): bool ns3::dsdv::RoutingTable::AddIpv4Event(ns3::Ipv4Address address, ns3::EventId id) [member function]
     cls.add_method('AddIpv4Event', 
                    'bool', 
-                   [param('ns3::Ipv4Address', 'arg0'), param('ns3::EventId', 'arg1')])
+                   [param('ns3::Ipv4Address', 'address'), param('ns3::EventId', 'id')])
     ## dsdv-rtable.h (module 'dsdv'): bool ns3::dsdv::RoutingTable::AddRoute(ns3::dsdv::RoutingTableEntry & r) [member function]
     cls.add_method('AddRoute', 
                    'bool', 
--- a/src/dsdv/bindings/modulegen__gcc_LP64.py	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/dsdv/bindings/modulegen__gcc_LP64.py	Fri Dec 16 18:51:18 2011 +0100
@@ -5303,10 +5303,10 @@
     cls.add_constructor([param('ns3::dsdv::RoutingTable const &', 'arg0')])
     ## dsdv-rtable.h (module 'dsdv'): ns3::dsdv::RoutingTable::RoutingTable() [constructor]
     cls.add_constructor([])
-    ## dsdv-rtable.h (module 'dsdv'): bool ns3::dsdv::RoutingTable::AddIpv4Event(ns3::Ipv4Address arg0, ns3::EventId arg1) [member function]
+    ## dsdv-rtable.h (module 'dsdv'): bool ns3::dsdv::RoutingTable::AddIpv4Event(ns3::Ipv4Address address, ns3::EventId id) [member function]
     cls.add_method('AddIpv4Event', 
                    'bool', 
-                   [param('ns3::Ipv4Address', 'arg0'), param('ns3::EventId', 'arg1')])
+                   [param('ns3::Ipv4Address', 'address'), param('ns3::EventId', 'id')])
     ## dsdv-rtable.h (module 'dsdv'): bool ns3::dsdv::RoutingTable::AddRoute(ns3::dsdv::RoutingTableEntry & r) [member function]
     cls.add_method('AddRoute', 
                    'bool', 
--- a/src/dsdv/model/dsdv-packet-queue.h	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/dsdv/model/dsdv-packet-queue.h	Fri Dec 16 18:51:18 2011 +0100
@@ -47,7 +47,7 @@
 public:
   typedef Ipv4RoutingProtocol::UnicastForwardCallback UnicastForwardCallback;
   typedef Ipv4RoutingProtocol::ErrorCallback ErrorCallback;
-  // / c-tor
+  /// c-tor
   QueueEntry (Ptr<const Packet> pa = 0, Ipv4Header const & h = Ipv4Header (),
               UnicastForwardCallback ucb = UnicastForwardCallback (),
               ErrorCallback ecb = ErrorCallback ())
@@ -67,7 +67,7 @@
   {
     return ((m_packet == o.m_packet) && (m_header.GetDestination () == o.m_header.GetDestination ()) && (m_expire == o.m_expire));
   }
-  // /\name Fields
+  ///\name Fields
   // \{
   UnicastForwardCallback GetUnicastForwardCallback () const
   {
@@ -111,15 +111,15 @@
   }
   // \}
 private:
-  // / Data packet
+  /// Data packet
   Ptr<const Packet> m_packet;
-  // / IP header
+  /// IP header
   Ipv4Header m_header;
-  // / Unicast forward callback
+  /// Unicast forward callback
   UnicastForwardCallback m_ucb;
-  // / Error callback
+  /// Error callback
   ErrorCallback m_ecb;
-  // / Expire time for queue entry
+  /// Expire time for queue entry
   Time m_expire;
 };
 /**
@@ -133,24 +133,24 @@
 class PacketQueue
 {
 public:
-  // / Default c-tor
+  /// Default c-tor
   PacketQueue ()
   {
   }
-  // / Push entry in queue, if there is no entry with the same packet and destination address in queue.
+  /// Push entry in queue, if there is no entry with the same packet and destination address in queue.
   bool Enqueue (QueueEntry & entry);
-  // / Return first found (the earliest) entry for given destination
+  /// Return first found (the earliest) entry for given destination
   bool Dequeue (Ipv4Address dst, QueueEntry & entry);
-  // / Remove all packets with destination IP address dst
+  /// Remove all packets with destination IP address dst
   void DropPacketWithDst (Ipv4Address dst);
-  // / Finds whether a packet with destination dst exists in the queue
+  /// Finds whether a packet with destination dst exists in the queue
   bool Find (Ipv4Address dst);
-  // / Get count of packets with destination dst in the queue
+  /// Get count of packets with destination dst in the queue
   uint32_t
   GetCountForPacketsWithDst (Ipv4Address dst);
-  // / Number of entries
+  /// Number of entries
   uint32_t GetSize ();
-  // /\name Fields
+  ///\name Fields
   // \{
   uint32_t GetMaxQueueLen () const
   {
@@ -180,15 +180,15 @@
 
 private:
   std::vector<QueueEntry> m_queue;
-  // / Remove all expired entries
+  /// Remove all expired entries
   void Purge ();
-  // / Notify that packet is dropped from queue by timeout
+  /// Notify that packet is dropped from queue by timeout
   void Drop (QueueEntry en, std::string reason);
-  // / The maximum number of packets that we allow a routing protocol to buffer.
+  /// The maximum number of packets that we allow a routing protocol to buffer.
   uint32_t m_maxLen;
-  // / The maximum number of packets that we allow per destination to buffer.
+  /// The maximum number of packets that we allow per destination to buffer.
   uint32_t m_maxLenPerDst;
-  // / The maximum period of time that a routing protocol is allowed to buffer a packet for, seconds.
+  /// The maximum period of time that a routing protocol is allowed to buffer a packet for, seconds.
   Time m_queueTimeout;
   static bool IsEqual (QueueEntry en, const Ipv4Address dst)
   {
--- a/src/dsdv/model/dsdv-packet.h	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/dsdv/model/dsdv-packet.h	Fri Dec 16 18:51:18 2011 +0100
@@ -98,9 +98,9 @@
     return m_dstSeqNo;
   }
 private:
-  Ipv4Address m_dst;     // /< Destination IP Address
-  uint32_t m_hopCount;     // /< Number of Hops
-  uint32_t m_dstSeqNo;     // /< Destination Sequence Number
+  Ipv4Address m_dst; ///< Destination IP Address
+  uint32_t m_hopCount; ///< Number of Hops
+  uint32_t m_dstSeqNo; ///< Destination Sequence Number
 };
 static inline std::ostream & operator<< (std::ostream& os, const DsdvHeader & packet)
 {
--- a/src/dsdv/model/dsdv-routing-protocol.cc	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/dsdv/model/dsdv-routing-protocol.cc	Fri Dec 16 18:51:18 2011 +0100
@@ -47,13 +47,13 @@
 namespace dsdv {
 NS_OBJECT_ENSURE_REGISTERED (RoutingProtocol);
 
-// / UDP Port for DSDV control traffic
+/// UDP Port for DSDV control traffic
 const uint32_t RoutingProtocol::DSDV_PORT = 269;
 
-// / Tag used by DSDV implementation
+/// Tag used by DSDV implementation
 struct DeferredRouteOutputTag : public Tag
 {
-  // / Positive if output device is fixed in RouteOutput
+  /// Positive if output device is fixed in RouteOutput
   int32_t oif;
 
   DeferredRouteOutputTag (int32_t o = -1)
--- a/src/dsdv/model/dsdv-routing-protocol.h	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/dsdv/model/dsdv-routing-protocol.h	Fri Dec 16 18:51:18 2011 +0100
@@ -56,14 +56,14 @@
   GetTypeId (void);
   static const uint32_t DSDV_PORT;
 
-  // / c-tor
+  /// c-tor
   RoutingProtocol ();
   virtual
   ~RoutingProtocol ();
   virtual void
   DoDispose ();
 
-  // /\name From Ipv4RoutingProtocol
+  ///\name From Ipv4RoutingProtocol
   // \{
   Ptr<Ipv4Route> RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr);
   bool RouteInput (Ptr<const Packet> p, const Ipv4Header &header, Ptr<const NetDevice> idev, UnicastForwardCallback ucb,
@@ -75,7 +75,7 @@
   virtual void NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address);
   virtual void SetIpv4 (Ptr<Ipv4> ipv4);
   // \}
-  // /\name Methods to handle protocol parameters
+  ///\name Methods to handle protocol parameters
   // \{
   void SetEnableBufferFlag (bool f);
   bool GetEnableBufferFlag () const;
@@ -86,64 +86,63 @@
   // \}
 
 private:
-  // /\name Protocol parameters.
+  ///\name Protocol parameters.
   // \{
-  // / \{Holdtimes is the multiplicative factor of PeriodicUpdateInterval for which the node waits since the last update
-  // / before flushing a route from the routing table. If PeriodicUpdateInterval is 8s and Holdtimes is 3, the node
-  // / waits for 24s since the last update to flush this route from its routing table. \}
+  /// Holdtimes is the multiplicative factor of PeriodicUpdateInterval for which the node waits since the last update
+  /// before flushing a route from the routing table. If PeriodicUpdateInterval is 8s and Holdtimes is 3, the node
+  /// waits for 24s since the last update to flush this route from its routing table.
   uint32_t Holdtimes;
-  // / \{PeriodicUpdateInterval specifies the periodic time interval between which the a node broadcasts
-  // / its entire routing table.\}
+  /// PeriodicUpdateInterval specifies the periodic time interval between which the a node broadcasts
+  /// its entire routing table.
   Time m_periodicUpdateInterval;
-  // /\{ SettlingTime specifies the time for which a node waits before propagating an update.
-  // / It waits for this time interval in hope of receiving an update with a better metric.
-  // /\}
+  /// SettlingTime specifies the time for which a node waits before propagating an update.
+  /// It waits for this time interval in hope of receiving an update with a better metric.
   Time m_settlingTime;
-  // /Nodes IP address
+  /// Nodes IP address
   Ipv4Address m_mainAddress;
-  // / IP protocol
+  /// IP protocol
   Ptr<Ipv4> m_ipv4;
-  // / Raw socket per each IP interface, map socket -> iface address (IP + mask)
+  /// Raw socket per each IP interface, map socket -> iface address (IP + mask)
   std::map<Ptr<Socket>, Ipv4InterfaceAddress> m_socketAddresses;
-  // / Loopback device used to defer route requests until a route is found
+  /// Loopback device used to defer route requests until a route is found
   Ptr<NetDevice> m_lo;
-  // / Main Routing table for the node
+  /// Main Routing table for the node
   RoutingTable m_routingTable;
-  // / Advertised Routing table for the node
+  /// Advertised Routing table for the node
   RoutingTable m_advRoutingTable;
-  // / The maximum number of packets that we allow a routing protocol to buffer.
+  /// The maximum number of packets that we allow a routing protocol to buffer.
   uint32_t m_maxQueueLen;
-  // / The maximum number of packets that we allow per destination to buffer.
+  /// The maximum number of packets that we allow per destination to buffer.
   uint32_t m_maxQueuedPacketsPerDst;
-  // /< The maximum period of time that a routing protocol is allowed to buffer a packet for.
+  /// The maximum period of time that a routing protocol is allowed to buffer a packet for.
   Time m_maxQueueTime;
-  // / A "drop front on full" queue used by the routing layer to buffer packets to which it does not have a route.
+  /// A "drop front on full" queue used by the routing layer to buffer packets to which it does not have a route.
   PacketQueue m_queue;
-  // / Flag that is used to enable or disable buffering
+  /// Flag that is used to enable or disable buffering
   bool EnableBuffering;
-  // / Flag that is used to enable or disable Weighted Settling Time
+  /// Flag that is used to enable or disable Weighted Settling Time
   bool EnableWST;
-  // / This is the wighted factor to determine the weighted settling time
+  /// This is the wighted factor to determine the weighted settling time
   double m_weightedFactor;
-  // / This is a flag to enable route aggregation. Route aggregation will aggregate all routes for
-  // / 'RouteAggregationTime' from the time an update is received by a node and sends them as a single update .
+  /// This is a flag to enable route aggregation. Route aggregation will aggregate all routes for
+  /// 'RouteAggregationTime' from the time an update is received by a node and sends them as a single update .
   bool EnableRouteAggregation;
-  // / Parameter that holds the route aggregation time interval
+  /// Parameter that holds the route aggregation time interval
   Time m_routeAggregationTime;
-  // / Unicast callback for own packets
+  /// Unicast callback for own packets
   UnicastForwardCallback m_scb;
-  // / Error callback for own packets
+  /// Error callback for own packets
   ErrorCallback m_ecb;
-  // /\}
+  // \}
 
 private:
-  // / Start protocol operation
+  /// Start protocol operation
   void
   Start ();
-  // / Queue packet untill we find a route
+  /// Queue packet untill we find a route
   void
   DeferredRouteOutput (Ptr<const Packet> p, const Ipv4Header & header, UnicastForwardCallback ucb, ErrorCallback ecb);
-  // / Look for any queued packets to send them out
+  /// Look for any queued packets to send them out
   void
   LookForQueuedPackets (void);
   /**
@@ -153,18 +152,18 @@
    */
   void
   SendPacketFromQueue (Ipv4Address dst, Ptr<Ipv4Route> route);
-  // / Find socket with local interface address iface
+  /// Find socket with local interface address iface
   Ptr<Socket>
   FindSocketWithInterfaceAddress (Ipv4InterfaceAddress iface) const;
-  // /\name Receive dsdv control packets
+  ///\name Receive dsdv control packets
   // \{
-  // / Receive and process dsdv control packet
+  /// Receive and process dsdv control packet
   void
   RecvDsdv (Ptr<Socket> socket);
   // \}
   void
   Send (Ptr<Ipv4Route>, Ptr<const Packet>, const Ipv4Header &);
-  // / Create loopback route for given header
+  /// Create loopback route for given header
   Ptr<Ipv4Route>
   LoopbackRoute (const Ipv4Header & header, Ptr<NetDevice> oif) const;
   /**
@@ -174,20 +173,20 @@
    */
   Time
   GetSettlingTime (Ipv4Address dst);
-  // / Sends trigger update from a node
+  /// Sends trigger update from a node
   void
   SendTriggeredUpdate ();
-  // / Broadcasts the entire routing table for every PeriodicUpdateInterval
+  /// Broadcasts the entire routing table for every PeriodicUpdateInterval
   void
   SendPeriodicUpdate ();
   void
   MergeTriggerPeriodicUpdates ();
-  // / Notify that packet is dropped for some reason
+  /// Notify that packet is dropped for some reason
   void
   Drop (Ptr<const Packet>, const Ipv4Header &, Socket::SocketErrno);
-  // / Timer to trigger periodic updates from a node
+  /// Timer to trigger periodic updates from a node
   Timer m_periodicUpdateTimer;
-  // / Timer used by the trigger updates in case of Weighted Settling Time is used
+  /// Timer used by the trigger updates in case of Weighted Settling Time is used
   Timer m_triggeredExpireTimer;
 };
 
--- a/src/dsdv/model/dsdv-rtable.h	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/dsdv/model/dsdv-rtable.h	Fri Dec 16 18:51:18 2011 +0100
@@ -56,7 +56,7 @@
 class RoutingTableEntry
 {
 public:
-  // / c-tor
+  /// c-tor
   RoutingTableEntry (Ptr<NetDevice> dev = 0, Ipv4Address dst = Ipv4Address (), u_int32_t m_seqNo = 0,
                      Ipv4InterfaceAddress iface = Ipv4InterfaceAddress (), u_int32_t hops = 0, Ipv4Address nextHop = Ipv4Address (),
                      Time lifetime = Simulator::Now (), Time SettlingTime = Simulator::Now (), bool changedEntries = false);
@@ -180,11 +180,11 @@
   Print (Ptr<OutputStreamWrapper> stream) const;
 
 private:
-  // /\name Fields
+  ///\name Fields
   // \{
-  // / Destination Sequence Number
+  /// Destination Sequence Number
   uint32_t m_seqNo;
-  // / Hop Count (number of hops needed to reach destination)
+  /// Hop Count (number of hops needed to reach destination)
   uint32_t m_hops;
   /**
    * \brief Expiration or deletion time of the route
@@ -200,16 +200,16 @@
    *   - output device
    */
   Ptr<Ipv4Route> m_ipv4Route;
-  // / Output interface address
+  /// Output interface address
   Ipv4InterfaceAddress m_iface;
-  // / Routing flags: valid, invalid or in search
+  /// Routing flags: valid, invalid or in search
   RouteFlags m_flag;
-  // / Time for which the node retains an update with changed metric before broadcasting it.
-  // / A node does that in hope of receiving a better update.
+  /// Time for which the node retains an update with changed metric before broadcasting it.
+  /// A node does that in hope of receiving a better update.
   Time m_settlingTime;
-  // / Flag to show if any of the routing table entries were changed with the routing update.
+  /// Flag to show if any of the routing table entries were changed with the routing update.
   uint32_t m_entriesChanged;
-  // \}
+  //\}
 };
 
 /**
@@ -219,7 +219,7 @@
 class RoutingTable
 {
 public:
-  // / c-tor
+  /// c-tor
   RoutingTable ();
   /**
    * Add routing table entry if it doesn't yet exist in routing table
@@ -247,14 +247,14 @@
   LookupRoute (Ipv4Address id, RoutingTableEntry & rt, bool forRouteInput);
   /**
    * Updating the routing Table with routing table entry rt
-   * \param routing table entry rt
+   * \param rt routing table entry
    * \return true on success
    */
   bool
   Update (RoutingTableEntry & rt);
   /**
    * Lookup list of addresses for which nxtHp is the next Hop address
-   * \param nexthop's address for which we want the list of destinations
+   * \param nxtHp nexthop's address for which we want the list of destinations
    * \param dstList is the list that will hold all these destination addresses
    */
   void
@@ -265,35 +265,35 @@
    */
   void
   GetListOfAllRoutes (std::map<Ipv4Address, RoutingTableEntry> & allRoutes);
-  // / Delete all route from interface with address iface
+  /// Delete all route from interface with address iface
   void
   DeleteAllRoutesFromInterface (Ipv4InterfaceAddress iface);
-  // / Delete all entries from routing table
+  /// Delete all entries from routing table
   void
   Clear ()
   {
     m_ipv4AddressEntry.clear ();
   }
-  // / Delete all outdated entries if Lifetime is expired
+  /// Delete all outdated entries if Lifetime is expired
   void
   Purge (std::map<Ipv4Address, RoutingTableEntry> & removedAddresses);
-  // / Print routing table
+  /// Print routing table
   void
   Print (Ptr<OutputStreamWrapper> stream) const;
-  // / Provides the number of routes present in that nodes routing table.
+  /// Provides the number of routes present in that nodes routing table.
   uint32_t
   RoutingTableSize ();
   /**
   * Add an event for a destination address so that the update to for that destination is sent
   * after the event is completed.
-  * \param destination address for which this event is running.
-  * \param unique eventid that was generated.
+  * \param address destination address for which this event is running.
+  * \param id unique eventid that was generated.
   */
   bool
-  AddIpv4Event (Ipv4Address, EventId);
+  AddIpv4Event (Ipv4Address address, EventId id);
   /**
   * Clear up the entry from the map after the event is completed
-  * \param destination address for which this event is running.
+  * \param address destination address for which this event is running.
   * \return true on success
   */
   bool
@@ -301,7 +301,7 @@
   /**
   * Force delete an update waiting for settling time to complete as a better update to
   * same destination was received.
-  * \param destination address for which this event is running.
+  * \param address destination address for which this event is running.
   * \return true on success
   */
   bool
@@ -309,19 +309,19 @@
   /**
   * Force delete an update waiting for settling time to complete as a better update to
   * same destination was received.
-  * \param destination address for which this event is running.
+  * \param address destination address for which this event is running.
   * \return true on finding out that an event is already running for that destination address.
   */
   bool
   ForceDeleteIpv4Event (Ipv4Address address);
   /**
     * Get the EcentId associated with that address.
-    * \param destination address for which this event is running.
+    * \param address destination address for which this event is running.
     * \return EventId on finding out an event is associated else return NULL.
     */
   EventId
   GetEventId (Ipv4Address address);
-  // /\name Handle life time of invalid route
+  ///\name Handle life time of invalid route
   // \{
   Time Getholddowntime () const
   {
@@ -334,13 +334,13 @@
   // \}
 
 private:
-  // /\name Fields
+  ///\name Fields
   // \{
-  // / an entry in the routing table.
+  /// an entry in the routing table.
   std::map<Ipv4Address, RoutingTableEntry> m_ipv4AddressEntry;
-  // / an entry in the event table.
+  /// an entry in the event table.
   std::map<Ipv4Address, EventId> m_ipv4Events;
-  // /
+  ///
   Time m_holddownTime;
   // \}
 };
--- a/src/internet/bindings/modulegen__gcc_ILP32.py	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/bindings/modulegen__gcc_ILP32.py	Fri Dec 16 18:51:18 2011 +0100
@@ -132,6 +132,8 @@
     module.add_class('Ipv6Address', import_from_module='ns.network')
     ## ipv6-address.h (module 'network'): ns3::Ipv6Address [class]
     root_module['ns3::Ipv6Address'].implicitly_converts_to(root_module['ns3::Address'])
+    ## ipv6-address-generator.h (module 'internet'): ns3::Ipv6AddressGenerator [class]
+    module.add_class('Ipv6AddressGenerator')
     ## ipv6-address-helper.h (module 'internet'): ns3::Ipv6AddressHelper [class]
     module.add_class('Ipv6AddressHelper')
     ## ipv6-interface-address.h (module 'internet'): ns3::Ipv6InterfaceAddress [class]
@@ -411,7 +413,7 @@
     ## tcp-header.h (module 'internet'): ns3::TcpHeader [class]
     module.add_class('TcpHeader', parent=root_module['ns3::Header'])
     ## tcp-header.h (module 'internet'): ns3::TcpHeader::Flags_t [enumeration]
-    module.add_enum('Flags_t', ['NONE', 'FIN', 'SYN', 'RST', 'PSH', 'ACK', 'URG'], outer_class=root_module['ns3::TcpHeader'])
+    module.add_enum('Flags_t', ['NONE', 'FIN', 'SYN', 'RST', 'PSH', 'ACK', 'URG', 'ECE', 'CWR'], outer_class=root_module['ns3::TcpHeader'])
     ## tcp-socket.h (module 'internet'): ns3::TcpSocket [class]
     module.add_class('TcpSocket', parent=root_module['ns3::Socket'])
     ## tcp-socket-factory.h (module 'internet'): ns3::TcpSocketFactory [class]
@@ -662,6 +664,7 @@
     register_Ns3Ipv4RoutingTableEntry_methods(root_module, root_module['ns3::Ipv4RoutingTableEntry'])
     register_Ns3Ipv4StaticRoutingHelper_methods(root_module, root_module['ns3::Ipv4StaticRoutingHelper'])
     register_Ns3Ipv6Address_methods(root_module, root_module['ns3::Ipv6Address'])
+    register_Ns3Ipv6AddressGenerator_methods(root_module, root_module['ns3::Ipv6AddressGenerator'])
     register_Ns3Ipv6AddressHelper_methods(root_module, root_module['ns3::Ipv6AddressHelper'])
     register_Ns3Ipv6InterfaceAddress_methods(root_module, root_module['ns3::Ipv6InterfaceAddress'])
     register_Ns3Ipv6InterfaceContainer_methods(root_module, root_module['ns3::Ipv6InterfaceContainer'])
@@ -2748,6 +2751,58 @@
                    [param('uint8_t *', 'address')])
     return
 
+def register_Ns3Ipv6AddressGenerator_methods(root_module, cls):
+    ## ipv6-address-generator.h (module 'internet'): ns3::Ipv6AddressGenerator::Ipv6AddressGenerator() [constructor]
+    cls.add_constructor([])
+    ## ipv6-address-generator.h (module 'internet'): ns3::Ipv6AddressGenerator::Ipv6AddressGenerator(ns3::Ipv6AddressGenerator const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::Ipv6AddressGenerator const &', 'arg0')])
+    ## ipv6-address-generator.h (module 'internet'): static bool ns3::Ipv6AddressGenerator::AddAllocated(ns3::Ipv6Address const addr) [member function]
+    cls.add_method('AddAllocated', 
+                   'bool', 
+                   [param('ns3::Ipv6Address const', 'addr')], 
+                   is_static=True)
+    ## ipv6-address-generator.h (module 'internet'): static ns3::Ipv6Address ns3::Ipv6AddressGenerator::GetAddress(ns3::Ipv6Prefix const prefix) [member function]
+    cls.add_method('GetAddress', 
+                   'ns3::Ipv6Address', 
+                   [param('ns3::Ipv6Prefix const', 'prefix')], 
+                   is_static=True)
+    ## ipv6-address-generator.h (module 'internet'): static ns3::Ipv6Address ns3::Ipv6AddressGenerator::GetNetwork(ns3::Ipv6Prefix const prefix) [member function]
+    cls.add_method('GetNetwork', 
+                   'ns3::Ipv6Address', 
+                   [param('ns3::Ipv6Prefix const', 'prefix')], 
+                   is_static=True)
+    ## ipv6-address-generator.h (module 'internet'): static void ns3::Ipv6AddressGenerator::Init(ns3::Ipv6Address const net, ns3::Ipv6Prefix const prefix, ns3::Ipv6Address const interfaceId="::1") [member function]
+    cls.add_method('Init', 
+                   'void', 
+                   [param('ns3::Ipv6Address const', 'net'), param('ns3::Ipv6Prefix const', 'prefix'), param('ns3::Ipv6Address const', 'interfaceId', default_value='"::1"')], 
+                   is_static=True)
+    ## ipv6-address-generator.h (module 'internet'): static void ns3::Ipv6AddressGenerator::InitAddress(ns3::Ipv6Address const interfaceId, ns3::Ipv6Prefix const prefix) [member function]
+    cls.add_method('InitAddress', 
+                   'void', 
+                   [param('ns3::Ipv6Address const', 'interfaceId'), param('ns3::Ipv6Prefix const', 'prefix')], 
+                   is_static=True)
+    ## ipv6-address-generator.h (module 'internet'): static ns3::Ipv6Address ns3::Ipv6AddressGenerator::NextAddress(ns3::Ipv6Prefix const prefix) [member function]
+    cls.add_method('NextAddress', 
+                   'ns3::Ipv6Address', 
+                   [param('ns3::Ipv6Prefix const', 'prefix')], 
+                   is_static=True)
+    ## ipv6-address-generator.h (module 'internet'): static ns3::Ipv6Address ns3::Ipv6AddressGenerator::NextNetwork(ns3::Ipv6Prefix const prefix) [member function]
+    cls.add_method('NextNetwork', 
+                   'ns3::Ipv6Address', 
+                   [param('ns3::Ipv6Prefix const', 'prefix')], 
+                   is_static=True)
+    ## ipv6-address-generator.h (module 'internet'): static void ns3::Ipv6AddressGenerator::Reset() [member function]
+    cls.add_method('Reset', 
+                   'void', 
+                   [], 
+                   is_static=True)
+    ## ipv6-address-generator.h (module 'internet'): static void ns3::Ipv6AddressGenerator::TestMode() [member function]
+    cls.add_method('TestMode', 
+                   'void', 
+                   [], 
+                   is_static=True)
+    return
+
 def register_Ns3Ipv6AddressHelper_methods(root_module, cls):
     ## ipv6-address-helper.h (module 'internet'): ns3::Ipv6AddressHelper::Ipv6AddressHelper(ns3::Ipv6AddressHelper const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::Ipv6AddressHelper const &', 'arg0')])
@@ -7814,6 +7869,11 @@
                    'uint32_t', 
                    [], 
                    is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True)
+    ## tcp-socket.h (module 'internet'): bool ns3::TcpSocket::GetTcpNoDelay() const [member function]
+    cls.add_method('GetTcpNoDelay', 
+                   'bool', 
+                   [], 
+                   is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True)
     ## tcp-socket.h (module 'internet'): void ns3::TcpSocket::SetConnCount(uint32_t count) [member function]
     cls.add_method('SetConnCount', 
                    'void', 
@@ -7864,6 +7924,11 @@
                    'void', 
                    [param('uint32_t', 'size')], 
                    is_pure_virtual=True, visibility='private', is_virtual=True)
+    ## tcp-socket.h (module 'internet'): void ns3::TcpSocket::SetTcpNoDelay(bool noDelay) [member function]
+    cls.add_method('SetTcpNoDelay', 
+                   'void', 
+                   [param('bool', 'noDelay')], 
+                   is_pure_virtual=True, visibility='private', is_virtual=True)
     return
 
 def register_Ns3TcpSocketFactory_methods(root_module, cls):
--- a/src/internet/bindings/modulegen__gcc_LP64.py	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/bindings/modulegen__gcc_LP64.py	Fri Dec 16 18:51:18 2011 +0100
@@ -132,6 +132,8 @@
     module.add_class('Ipv6Address', import_from_module='ns.network')
     ## ipv6-address.h (module 'network'): ns3::Ipv6Address [class]
     root_module['ns3::Ipv6Address'].implicitly_converts_to(root_module['ns3::Address'])
+    ## ipv6-address-generator.h (module 'internet'): ns3::Ipv6AddressGenerator [class]
+    module.add_class('Ipv6AddressGenerator')
     ## ipv6-address-helper.h (module 'internet'): ns3::Ipv6AddressHelper [class]
     module.add_class('Ipv6AddressHelper')
     ## ipv6-interface-address.h (module 'internet'): ns3::Ipv6InterfaceAddress [class]
@@ -411,7 +413,7 @@
     ## tcp-header.h (module 'internet'): ns3::TcpHeader [class]
     module.add_class('TcpHeader', parent=root_module['ns3::Header'])
     ## tcp-header.h (module 'internet'): ns3::TcpHeader::Flags_t [enumeration]
-    module.add_enum('Flags_t', ['NONE', 'FIN', 'SYN', 'RST', 'PSH', 'ACK', 'URG'], outer_class=root_module['ns3::TcpHeader'])
+    module.add_enum('Flags_t', ['NONE', 'FIN', 'SYN', 'RST', 'PSH', 'ACK', 'URG', 'ECE', 'CWR'], outer_class=root_module['ns3::TcpHeader'])
     ## tcp-socket.h (module 'internet'): ns3::TcpSocket [class]
     module.add_class('TcpSocket', parent=root_module['ns3::Socket'])
     ## tcp-socket-factory.h (module 'internet'): ns3::TcpSocketFactory [class]
@@ -662,6 +664,7 @@
     register_Ns3Ipv4RoutingTableEntry_methods(root_module, root_module['ns3::Ipv4RoutingTableEntry'])
     register_Ns3Ipv4StaticRoutingHelper_methods(root_module, root_module['ns3::Ipv4StaticRoutingHelper'])
     register_Ns3Ipv6Address_methods(root_module, root_module['ns3::Ipv6Address'])
+    register_Ns3Ipv6AddressGenerator_methods(root_module, root_module['ns3::Ipv6AddressGenerator'])
     register_Ns3Ipv6AddressHelper_methods(root_module, root_module['ns3::Ipv6AddressHelper'])
     register_Ns3Ipv6InterfaceAddress_methods(root_module, root_module['ns3::Ipv6InterfaceAddress'])
     register_Ns3Ipv6InterfaceContainer_methods(root_module, root_module['ns3::Ipv6InterfaceContainer'])
@@ -2748,6 +2751,58 @@
                    [param('uint8_t *', 'address')])
     return
 
+def register_Ns3Ipv6AddressGenerator_methods(root_module, cls):
+    ## ipv6-address-generator.h (module 'internet'): ns3::Ipv6AddressGenerator::Ipv6AddressGenerator() [constructor]
+    cls.add_constructor([])
+    ## ipv6-address-generator.h (module 'internet'): ns3::Ipv6AddressGenerator::Ipv6AddressGenerator(ns3::Ipv6AddressGenerator const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::Ipv6AddressGenerator const &', 'arg0')])
+    ## ipv6-address-generator.h (module 'internet'): static bool ns3::Ipv6AddressGenerator::AddAllocated(ns3::Ipv6Address const addr) [member function]
+    cls.add_method('AddAllocated', 
+                   'bool', 
+                   [param('ns3::Ipv6Address const', 'addr')], 
+                   is_static=True)
+    ## ipv6-address-generator.h (module 'internet'): static ns3::Ipv6Address ns3::Ipv6AddressGenerator::GetAddress(ns3::Ipv6Prefix const prefix) [member function]
+    cls.add_method('GetAddress', 
+                   'ns3::Ipv6Address', 
+                   [param('ns3::Ipv6Prefix const', 'prefix')], 
+                   is_static=True)
+    ## ipv6-address-generator.h (module 'internet'): static ns3::Ipv6Address ns3::Ipv6AddressGenerator::GetNetwork(ns3::Ipv6Prefix const prefix) [member function]
+    cls.add_method('GetNetwork', 
+                   'ns3::Ipv6Address', 
+                   [param('ns3::Ipv6Prefix const', 'prefix')], 
+                   is_static=True)
+    ## ipv6-address-generator.h (module 'internet'): static void ns3::Ipv6AddressGenerator::Init(ns3::Ipv6Address const net, ns3::Ipv6Prefix const prefix, ns3::Ipv6Address const interfaceId="::1") [member function]
+    cls.add_method('Init', 
+                   'void', 
+                   [param('ns3::Ipv6Address const', 'net'), param('ns3::Ipv6Prefix const', 'prefix'), param('ns3::Ipv6Address const', 'interfaceId', default_value='"::1"')], 
+                   is_static=True)
+    ## ipv6-address-generator.h (module 'internet'): static void ns3::Ipv6AddressGenerator::InitAddress(ns3::Ipv6Address const interfaceId, ns3::Ipv6Prefix const prefix) [member function]
+    cls.add_method('InitAddress', 
+                   'void', 
+                   [param('ns3::Ipv6Address const', 'interfaceId'), param('ns3::Ipv6Prefix const', 'prefix')], 
+                   is_static=True)
+    ## ipv6-address-generator.h (module 'internet'): static ns3::Ipv6Address ns3::Ipv6AddressGenerator::NextAddress(ns3::Ipv6Prefix const prefix) [member function]
+    cls.add_method('NextAddress', 
+                   'ns3::Ipv6Address', 
+                   [param('ns3::Ipv6Prefix const', 'prefix')], 
+                   is_static=True)
+    ## ipv6-address-generator.h (module 'internet'): static ns3::Ipv6Address ns3::Ipv6AddressGenerator::NextNetwork(ns3::Ipv6Prefix const prefix) [member function]
+    cls.add_method('NextNetwork', 
+                   'ns3::Ipv6Address', 
+                   [param('ns3::Ipv6Prefix const', 'prefix')], 
+                   is_static=True)
+    ## ipv6-address-generator.h (module 'internet'): static void ns3::Ipv6AddressGenerator::Reset() [member function]
+    cls.add_method('Reset', 
+                   'void', 
+                   [], 
+                   is_static=True)
+    ## ipv6-address-generator.h (module 'internet'): static void ns3::Ipv6AddressGenerator::TestMode() [member function]
+    cls.add_method('TestMode', 
+                   'void', 
+                   [], 
+                   is_static=True)
+    return
+
 def register_Ns3Ipv6AddressHelper_methods(root_module, cls):
     ## ipv6-address-helper.h (module 'internet'): ns3::Ipv6AddressHelper::Ipv6AddressHelper(ns3::Ipv6AddressHelper const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::Ipv6AddressHelper const &', 'arg0')])
@@ -7814,6 +7869,11 @@
                    'uint32_t', 
                    [], 
                    is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True)
+    ## tcp-socket.h (module 'internet'): bool ns3::TcpSocket::GetTcpNoDelay() const [member function]
+    cls.add_method('GetTcpNoDelay', 
+                   'bool', 
+                   [], 
+                   is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True)
     ## tcp-socket.h (module 'internet'): void ns3::TcpSocket::SetConnCount(uint32_t count) [member function]
     cls.add_method('SetConnCount', 
                    'void', 
@@ -7864,6 +7924,11 @@
                    'void', 
                    [param('uint32_t', 'size')], 
                    is_pure_virtual=True, visibility='private', is_virtual=True)
+    ## tcp-socket.h (module 'internet'): void ns3::TcpSocket::SetTcpNoDelay(bool noDelay) [member function]
+    cls.add_method('SetTcpNoDelay', 
+                   'void', 
+                   [param('bool', 'noDelay')], 
+                   is_pure_virtual=True, visibility='private', is_virtual=True)
     return
 
 def register_Ns3TcpSocketFactory_methods(root_module, cls):
--- a/src/internet/helper/internet-stack-helper.cc	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/helper/internet-stack-helper.cc	Fri Dec 16 18:51:18 2011 +0100
@@ -623,6 +623,40 @@
 }
 
 static void
+Ipv4L3ProtocolTxSinkWithoutContext (
+  Ptr<OutputStreamWrapper> stream,
+  Ptr<const Packet> packet,
+  Ptr<Ipv4> ipv4, 
+  uint32_t interface)
+{
+  InterfacePairIpv4 pair = std::make_pair (ipv4, interface);
+  if (g_interfaceStreamMapIpv4.find (pair) == g_interfaceStreamMapIpv4.end ())
+    {
+      NS_LOG_INFO ("Ignoring packet to/from interface " << interface);
+      return;
+    }
+
+  *stream->GetStream () << "t " << Simulator::Now ().GetSeconds () << " " << *packet << std::endl;
+}
+
+static void
+Ipv4L3ProtocolRxSinkWithoutContext (
+  Ptr<OutputStreamWrapper> stream,
+  Ptr<const Packet> packet,
+  Ptr<Ipv4> ipv4, 
+  uint32_t interface)
+{
+  InterfacePairIpv4 pair = std::make_pair (ipv4, interface);
+  if (g_interfaceStreamMapIpv4.find (pair) == g_interfaceStreamMapIpv4.end ())
+    {
+      NS_LOG_INFO ("Ignoring packet to/from interface " << interface);
+      return;
+    }
+
+  *stream->GetStream () << "r " << Simulator::Now ().GetSeconds () << " " << *packet << std::endl;
+}
+
+static void
 Ipv4L3ProtocolDropSinkWithContext (
   Ptr<OutputStreamWrapper> stream,
   std::string context,
@@ -655,6 +689,52 @@
 #endif
 }
 
+static void
+Ipv4L3ProtocolTxSinkWithContext (
+  Ptr<OutputStreamWrapper> stream,
+  std::string context,
+  Ptr<const Packet> packet,
+  Ptr<Ipv4> ipv4, 
+  uint32_t interface)
+{
+  InterfacePairIpv4 pair = std::make_pair (ipv4, interface);
+  if (g_interfaceStreamMapIpv4.find (pair) == g_interfaceStreamMapIpv4.end ())
+    {
+      NS_LOG_INFO ("Ignoring packet to/from interface " << interface);
+      return;
+    }
+
+#ifdef INTERFACE_CONTEXT
+  *stream->GetStream () << "t " << Simulator::Now ().GetSeconds () << " " << context << "(" << interface << ") " 
+                        << *packet << std::endl;
+#else
+  *stream->GetStream () << "t " << Simulator::Now ().GetSeconds () << " " << context << " "  << *packet << std::endl;
+#endif
+}
+
+static void
+Ipv4L3ProtocolRxSinkWithContext (
+  Ptr<OutputStreamWrapper> stream,
+  std::string context,
+  Ptr<const Packet> packet,
+  Ptr<Ipv4> ipv4, 
+  uint32_t interface)
+{
+  InterfacePairIpv4 pair = std::make_pair (ipv4, interface);
+  if (g_interfaceStreamMapIpv4.find (pair) == g_interfaceStreamMapIpv4.end ())
+    {
+      NS_LOG_INFO ("Ignoring packet to/from interface " << interface);
+      return;
+    }
+
+#ifdef INTERFACE_CONTEXT
+  *stream->GetStream () << "r " << Simulator::Now ().GetSeconds () << " " << context << "(" << interface << ") " 
+                        << *packet << std::endl;
+#else
+  *stream->GetStream () << "r " << Simulator::Now ().GetSeconds () << " " << context << " "  << *packet << std::endl;
+#endif
+}
+
 bool
 InternetStackHelper::AsciiHooked (Ptr<Ipv4> ipv4)
 {
@@ -744,8 +824,16 @@
           Ptr<Ipv4L3Protocol> ipv4L3Protocol = ipv4->GetObject<Ipv4L3Protocol> ();
           bool __attribute__ ((unused)) result = ipv4L3Protocol->TraceConnectWithoutContext ("Drop", 
                                                                                              MakeBoundCallback (&Ipv4L3ProtocolDropSinkWithoutContext, theStream));
-          NS_ASSERT_MSG (result == true, "InternetStackHelper::EanableAsciiIpv4Internal():  "
+          NS_ASSERT_MSG (result == true, "InternetStackHelper::EnableAsciiIpv4Internal():  "
                          "Unable to connect ipv4L3Protocol \"Drop\"");
+          result = ipv4L3Protocol->TraceConnectWithoutContext ("Tx", 
+                                                               MakeBoundCallback (&Ipv4L3ProtocolTxSinkWithoutContext, theStream));
+          NS_ASSERT_MSG (result == true, "InternetStackHelper::EnableAsciiIpv4Internal():  "
+                         "Unable to connect ipv4L3Protocol \"Tx\"");
+          result = ipv4L3Protocol->TraceConnectWithoutContext ("Rx", 
+                                                               MakeBoundCallback (&Ipv4L3ProtocolRxSinkWithoutContext, theStream));
+          NS_ASSERT_MSG (result == true, "InternetStackHelper::EnableAsciiIpv4Internal():  "
+                         "Unable to connect ipv4L3Protocol \"Rx\"");
         }
 
       g_interfaceStreamMapIpv4[std::make_pair (ipv4, interface)] = theStream;
@@ -785,6 +873,12 @@
       oss.str ("");
       oss << "/NodeList/" << node->GetId () << "/$ns3::Ipv4L3Protocol/Drop";
       Config::Connect (oss.str (), MakeBoundCallback (&Ipv4L3ProtocolDropSinkWithContext, stream));
+      oss.str ("");
+      oss << "/NodeList/" << node->GetId () << "/$ns3::Ipv4L3Protocol/Tx";
+      Config::Connect (oss.str (), MakeBoundCallback (&Ipv4L3ProtocolTxSinkWithContext, stream));
+      oss.str ("");
+      oss << "/NodeList/" << node->GetId () << "/$ns3::Ipv4L3Protocol/Rx";
+      Config::Connect (oss.str (), MakeBoundCallback (&Ipv4L3ProtocolRxSinkWithContext, stream));
     }
 
   g_interfaceStreamMapIpv4[std::make_pair (ipv4, interface)] = stream;
@@ -818,6 +912,40 @@
 }
 
 static void
+Ipv6L3ProtocolTxSinkWithoutContext (
+  Ptr<OutputStreamWrapper> stream,
+  Ptr<const Packet> packet,
+  Ptr<Ipv6> ipv6, 
+  uint32_t interface)
+{
+  InterfacePairIpv6 pair = std::make_pair (ipv6, interface);
+  if (g_interfaceStreamMapIpv6.find (pair) == g_interfaceStreamMapIpv6.end ())
+    {
+      NS_LOG_INFO ("Ignoring packet to/from interface " << interface);
+      return;
+    }
+
+  *stream->GetStream () << "t " << Simulator::Now ().GetSeconds () << " " << *packet << std::endl;
+}
+
+static void
+Ipv6L3ProtocolRxSinkWithoutContext (
+  Ptr<OutputStreamWrapper> stream,
+  Ptr<const Packet> packet,
+  Ptr<Ipv6> ipv6, 
+  uint32_t interface)
+{
+  InterfacePairIpv6 pair = std::make_pair (ipv6, interface);
+  if (g_interfaceStreamMapIpv6.find (pair) == g_interfaceStreamMapIpv6.end ())
+    {
+      NS_LOG_INFO ("Ignoring packet to/from interface " << interface);
+      return;
+    }
+
+  *stream->GetStream () << "r " << Simulator::Now ().GetSeconds () << " " << *packet << std::endl;
+}
+
+static void
 Ipv6L3ProtocolDropSinkWithContext (
   Ptr<OutputStreamWrapper> stream,
   std::string context,
@@ -850,6 +978,52 @@
 #endif
 }
 
+static void
+Ipv6L3ProtocolTxSinkWithContext (
+  Ptr<OutputStreamWrapper> stream,
+  std::string context,
+  Ptr<const Packet> packet,
+  Ptr<Ipv6> ipv6, 
+  uint32_t interface)
+{
+  InterfacePairIpv6 pair = std::make_pair (ipv6, interface);
+  if (g_interfaceStreamMapIpv6.find (pair) == g_interfaceStreamMapIpv6.end ())
+    {
+      NS_LOG_INFO ("Ignoring packet to/from interface " << interface);
+      return;
+    }
+
+#ifdef INTERFACE_CONTEXT
+  *stream->GetStream () << "t " << Simulator::Now ().GetSeconds () << " " << context << "(" << interface << ") " 
+                        << *packet << std::endl;
+#else
+  *stream->GetStream () << "t " << Simulator::Now ().GetSeconds () << " " << context << " " << *packet << std::endl;
+#endif
+}
+
+static void
+Ipv6L3ProtocolRxSinkWithContext (
+  Ptr<OutputStreamWrapper> stream,
+  std::string context,
+  Ptr<const Packet> packet,
+  Ptr<Ipv6> ipv6, 
+  uint32_t interface)
+{
+  InterfacePairIpv6 pair = std::make_pair (ipv6, interface);
+  if (g_interfaceStreamMapIpv6.find (pair) == g_interfaceStreamMapIpv6.end ())
+    {
+      NS_LOG_INFO ("Ignoring packet to/from interface " << interface);
+      return;
+    }
+
+#ifdef INTERFACE_CONTEXT
+  *stream->GetStream () << "r " << Simulator::Now ().GetSeconds () << " " << context << "(" << interface << ") " 
+                        << *packet << std::endl;
+#else
+  *stream->GetStream () << "r " << Simulator::Now ().GetSeconds () << " " << context << " " << *packet << std::endl;
+#endif
+}
+
 bool
 InternetStackHelper::AsciiHooked (Ptr<Ipv6> ipv6)
 {
@@ -933,6 +1107,14 @@
                                                                                              MakeBoundCallback (&Ipv6L3ProtocolDropSinkWithoutContext, theStream));
           NS_ASSERT_MSG (result == true, "InternetStackHelper::EnableAsciiIpv6Internal():  "
                          "Unable to connect ipv6L3Protocol \"Drop\"");
+          result = ipv6L3Protocol->TraceConnectWithoutContext ("Tx", 
+                                                               MakeBoundCallback (&Ipv6L3ProtocolTxSinkWithoutContext, theStream));
+          NS_ASSERT_MSG (result == true, "InternetStackHelper::EnableAsciiIpv6Internal():  "
+                         "Unable to connect ipv6L3Protocol \"Tx\"");
+          result = ipv6L3Protocol->TraceConnectWithoutContext ("Rx", 
+                                                               MakeBoundCallback (&Ipv6L3ProtocolRxSinkWithoutContext, theStream));
+          NS_ASSERT_MSG (result == true, "InternetStackHelper::EnableAsciiIpv6Internal():  "
+                         "Unable to connect ipv6L3Protocol \"Rx\"");
         }
 
       g_interfaceStreamMapIpv6[std::make_pair (ipv6, interface)] = theStream;
@@ -956,8 +1138,15 @@
       Ptr<Node> node = ipv6->GetObject<Node> ();
       std::ostringstream oss;
 
+      oss.str ("");
       oss << "/NodeList/" << node->GetId () << "/$ns3::Ipv6L3Protocol/Drop";
       Config::Connect (oss.str (), MakeBoundCallback (&Ipv6L3ProtocolDropSinkWithContext, stream));
+      oss.str ("");
+      oss << "/NodeList/" << node->GetId () << "/$ns3::Ipv6L3Protocol/Tx";
+      Config::Connect (oss.str (), MakeBoundCallback (&Ipv6L3ProtocolTxSinkWithContext, stream));
+      oss.str ("");
+      oss << "/NodeList/" << node->GetId () << "/$ns3::Ipv6L3Protocol/Rx";
+      Config::Connect (oss.str (), MakeBoundCallback (&Ipv6L3ProtocolRxSinkWithContext, stream));
     }
 
   g_interfaceStreamMapIpv6[std::make_pair (ipv6, interface)] = stream;
--- a/src/internet/helper/internet-stack-helper.h	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/helper/internet-stack-helper.h	Fri Dec 16 18:51:18 2011 +0100
@@ -209,12 +209,12 @@
                                         bool explicitFilename);
 
   /**
-   * @brief Enable pcap output the indicated Ipv4 and interface pair.
+   * @brief Enable pcap output the indicated Ipv6 and interface pair.
    * @internal
    *
    * @param prefix Filename prefix to use for pcap files.
-   * @param ipv4 Ptr to the Ipv4 interface on which you want to enable tracing.
-   * @param interface Interface ID on the Ipv4 on which you want to enable tracing.
+   * @param ipv6 Ptr to the Ipv6 interface on which you want to enable tracing.
+   * @param interface Interface ID on the Ipv6 on which you want to enable tracing.
    */
   virtual void EnablePcapIpv6Internal (std::string prefix, 
                                        Ptr<Ipv6> ipv6, 
@@ -222,14 +222,14 @@
                                        bool explicitFilename);
 
   /**
-   * @brief Enable ascii trace output on the indicated Ipv4 and interface pair.
+   * @brief Enable ascii trace output on the indicated Ipv6 and interface pair.
    * @internal
    *
    * @param stream An OutputStreamWrapper representing an existing file to use
    *               when writing trace data.
    * @param prefix Filename prefix to use for ascii trace files.
-   * @param ipv4 Ptr to the Ipv4 interface on which you want to enable tracing.
-   * @param interface Interface ID on the Ipv4 on which you want to enable tracing.
+   * @param ipv6 Ptr to the Ipv6 interface on which you want to enable tracing.
+   * @param interface Interface ID on the Ipv6 on which you want to enable tracing.
    */
   virtual void EnableAsciiIpv6Internal (Ptr<OutputStreamWrapper> stream, 
                                         std::string prefix, 
--- a/src/internet/model/ipv4-header.h	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/model/ipv4-header.h	Fri Dec 16 18:51:18 2011 +0100
@@ -111,7 +111,7 @@
     }; 
   /**
    * \brief Set ECN Field
-   * \param ECN Type
+   * \param ecn ECN Type
    */
   void SetEcn (EcnType ecn);
   /**
--- a/src/internet/model/ipv4-l3-protocol.cc	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/model/ipv4-l3-protocol.cc	Fri Dec 16 18:51:18 2011 +0100
@@ -1135,8 +1135,16 @@
 
   uint16_t offset = 0;
   bool moreFragment = true;
+  uint16_t originalOffset = 0;
+  bool alreadyFragmented = false;
   uint32_t currentFragmentablePartSize = 0;
 
+  if (!ipv4Header.IsLastFragment())
+    {
+      alreadyFragmented = true;
+      originalOffset = ipv4Header.GetFragmentOffset();
+    }
+
   // IPv4 fragments are all 8 bytes aligned but the last.
   // The IP payload size is:
   // floor( ( outIfaceMtu - ipv4Header.GetSerializedSize() ) /8 ) *8
@@ -1158,14 +1166,21 @@
         {
           moreFragment = false;
           currentFragmentablePartSize = p->GetSize () - offset;
-          fragmentHeader.SetLastFragment ();
+          if (alreadyFragmented)
+            {
+              fragmentHeader.SetMoreFragments ();
+            }
+          else
+            {
+              fragmentHeader.SetLastFragment ();
+            }
         }
 
       NS_LOG_LOGIC ("Fragment creation - " << offset << ", " << currentFragmentablePartSize  );
       Ptr<Packet> fragment = p->CreateFragment (offset, currentFragmentablePartSize);
       NS_LOG_LOGIC ("Fragment created - " << offset << ", " << fragment->GetSize ()  );
 
-      fragmentHeader.SetFragmentOffset (offset);
+      fragmentHeader.SetFragmentOffset (offset+originalOffset);
       fragmentHeader.SetPayloadSize (currentFragmentablePartSize);
 
       if (Node::ChecksumEnabled ())
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet/model/ipv6-address-generator.cc	Fri Dec 16 18:51:18 2011 +0100
@@ -0,0 +1,604 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 University of Washington
+ * Copyright (c) 2011 Atishay Jain
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <list>
+#include "ns3/abort.h"
+#include "ns3/assert.h"
+#include "ns3/log.h"
+#include "ns3/simulation-singleton.h"
+#include "ipv6-address-generator.h"
+
+NS_LOG_COMPONENT_DEFINE ("Ipv6AddressGenerator");
+
+namespace ns3 {
+
+class Ipv6AddressGeneratorImpl
+{
+public:
+  Ipv6AddressGeneratorImpl ();
+  virtual ~Ipv6AddressGeneratorImpl ();
+
+  void Init (const Ipv6Address net, const Ipv6Prefix prefix,
+             const Ipv6Address interfaceId);
+
+  Ipv6Address GetNetwork (const Ipv6Prefix prefix) const;
+  Ipv6Address NextNetwork (const Ipv6Prefix prefix);
+
+  void InitAddress (const Ipv6Address interfaceId, const Ipv6Prefix prefix);
+  Ipv6Address GetAddress (const Ipv6Prefix prefix) const;
+  Ipv6Address NextAddress (const Ipv6Prefix prefix);
+
+  void Reset (void);
+  bool AddAllocated (const Ipv6Address addr);
+
+  void TestMode (void);
+private:
+  static const uint32_t N_BITS = 128;
+  static const uint32_t MOST_SIGNIFICANT_BIT = 0x80;
+
+  uint32_t PrefixToIndex (Ipv6Prefix prefix) const;
+
+  class NetworkState
+  {
+public:
+    uint8_t prefix[16];
+    uint32_t shift;
+    uint8_t network[16];
+    uint8_t addr[16];
+    uint8_t addrMax[16];
+  };
+
+  NetworkState m_netTable[N_BITS];
+
+  class Entry
+  {
+public:
+    uint8_t addrLow[16];
+    uint8_t addrHigh[16];
+  };
+
+  std::list<Entry> m_entries;
+  Ipv6Address m_base;
+  bool m_test;
+};
+
+Ipv6AddressGeneratorImpl::Ipv6AddressGeneratorImpl ()
+  : m_entries (),
+    m_base ("::1"),
+    m_test (false)
+{
+  NS_LOG_FUNCTION (this);
+  Reset ();
+}
+
+void
+Ipv6AddressGeneratorImpl::Reset (void)
+{
+  NS_LOG_FUNCTION (this);
+
+  uint8_t prefix[16] = { 0};
+
+  for (uint32_t i = 0; i < N_BITS; ++i)
+    {
+      for (uint32_t j = 0; j < 16; ++j)
+        {
+          m_netTable[i].prefix[j] = prefix[j];
+        }
+      for (uint32_t j = 0; j < 15; ++j)
+        {
+          prefix[15 - j] >>= 1;
+          prefix[15 - j] |= (prefix[15 - j - 1] & 1);
+        }
+      prefix[0] |= MOST_SIGNIFICANT_BIT;
+      for (uint32_t j = 0; j < 15; ++j)
+        {
+          m_netTable[i].network[j] = 0;
+        }
+      m_netTable[i].network[15] = 1;
+      for (uint32_t j = 0; j < 15; ++j)
+        {
+          m_netTable[i].addr[j] = 0;
+        }
+      m_netTable[i].addr[15] = 1;
+      for (uint32_t j = 0; j < 16; ++j)
+        {
+          m_netTable[i].addrMax[j] = ~prefix[j];
+        }
+      m_netTable[i].shift = N_BITS - i;
+    }
+  m_entries.clear ();
+  m_base = Ipv6Address ("::1");
+  m_test = false;
+}
+
+Ipv6AddressGeneratorImpl::~Ipv6AddressGeneratorImpl ()
+{
+  NS_LOG_FUNCTION (this);
+}
+
+void
+Ipv6AddressGeneratorImpl::Init (
+  const Ipv6Address net,
+  const Ipv6Prefix prefix,
+  const Ipv6Address interfaceId)
+{
+  NS_LOG_FUNCTION (this << net << prefix << interfaceId);
+
+  m_base = interfaceId;
+  //
+  // We're going to be playing with the actual bits in the network and prefix so
+  // pull them out into ints.
+  //
+  uint8_t prefixBits[16];
+  prefix.GetBytes (prefixBits);
+  uint8_t netBits[16];
+  net.GetBytes (netBits);
+  uint8_t interfaceIdBits[16];
+  interfaceId.GetBytes (interfaceIdBits);
+  //
+  // Some quick reasonableness testing.
+  //
+  // Convert the network prefix into an index into the network number table.
+  // The network number comes in to us properly aligned for the prefix and so
+  // needs to be shifted right into the normalized position (lowest bit of the
+  // network number at bit zero of the int that holds it).
+  //
+  uint32_t index = PrefixToIndex (prefix);
+  uint32_t a = m_netTable[index].shift / 8;
+  uint32_t b = m_netTable[index].shift % 8;
+  for (int32_t j = 15 - a; j >= 0; j--)
+    {
+      m_netTable[index].network[j + a] = netBits[j];
+    }
+  for (uint32_t j = 0; j < a; j++)
+    {
+      m_netTable[index].network[j] = 0;
+    }
+  for (uint32_t j = 15; j >= a; j--)
+    {
+      m_netTable[index].network[j] = m_netTable[index].network[j] >> b;
+      m_netTable[index].network[j] |= m_netTable[index].network[j - 1] << (8 - b);
+    }
+  for (int32_t j = 0; j < 16; j++)
+    {
+      m_netTable[index].addr[j] = interfaceIdBits[j];
+    }
+  return;
+}
+
+Ipv6Address
+Ipv6AddressGeneratorImpl::GetNetwork (
+  const Ipv6Prefix prefix) const
+{
+  NS_LOG_FUNCTION (this);
+  uint8_t nw[16];
+  uint32_t index = PrefixToIndex (prefix);
+  uint32_t a = m_netTable[index].shift / 8;
+  uint32_t b = m_netTable[index].shift % 8;
+  for (uint32_t j = 0; j < 16 - a; ++j)
+    {
+      nw[j] = m_netTable[index].network[j + a];
+    }
+  for (uint32_t j = 16 - a; j < 16; ++j)
+    {
+      nw[j] = 0;
+    }
+  for (uint32_t j = 0; j < 15; j++)
+    {
+      nw[j] = nw[j] << b;
+      nw[j] |= nw[j + 1] >> (8 - b);
+    }
+  nw[15] = nw[15] << b;
+
+  return Ipv6Address (nw);
+}
+
+Ipv6Address
+Ipv6AddressGeneratorImpl::NextNetwork (
+  const Ipv6Prefix prefix)
+{
+  NS_LOG_FUNCTION (this);
+
+  uint32_t index = PrefixToIndex (prefix);
+  // Reset the base to what was initialized
+  uint8_t interfaceIdBits[16];
+  m_base.GetBytes (interfaceIdBits);
+  for (int32_t j = 0; j < 16; j++)
+    {
+      m_netTable[index].addr[j] = interfaceIdBits[j];
+    }
+
+  for (int32_t j = 15; j >= 0; j--)
+    {
+      if (m_netTable[index].network[j] < 0xff)
+        {
+          ++m_netTable[index].network[j];
+          break;
+        }
+      else
+        {
+          ++m_netTable[index].network[j];
+        }
+    }
+
+  uint8_t nw[16];
+  uint32_t a = m_netTable[index].shift / 8;
+  uint32_t b = m_netTable[index].shift % 8;
+  for (uint32_t j = 0; j < 16 - a; ++j)
+    {
+      nw[j] = m_netTable[index].network[j + a];
+    }
+  for (uint32_t j = 16 - a; j < 16; ++j)
+    {
+      nw[j] = 0;
+    }
+  for (uint32_t j = 0; j < 15; j++)
+    {
+      nw[j] = nw[j] << b;
+      nw[j] |= nw[j + 1] >> (8 - b);
+    }
+  nw[15] = nw[15] << b;
+
+  return Ipv6Address (nw);
+
+}
+
+void
+Ipv6AddressGeneratorImpl::InitAddress (
+  const Ipv6Address interfaceId,
+  const Ipv6Prefix prefix)
+{
+  NS_LOG_FUNCTION (this);
+
+  uint32_t index = PrefixToIndex (prefix);
+  uint8_t interfaceIdBits[16];
+  interfaceId.GetBytes (interfaceIdBits);
+
+  for (uint32_t j = 0; j < 16; ++j)
+    {
+      m_netTable[index].addr[j] = interfaceIdBits[j];
+    }
+}
+
+Ipv6Address
+Ipv6AddressGeneratorImpl::GetAddress (const Ipv6Prefix prefix) const
+{
+  NS_LOG_FUNCTION (this);
+
+  uint32_t index = PrefixToIndex (prefix);
+
+  uint8_t nw[16];
+  uint32_t a = m_netTable[index].shift / 8;
+  uint32_t b = m_netTable[index].shift % 8;
+  for (uint32_t j = 0; j < 16 - a; ++j)
+    {
+      nw[j] = m_netTable[index].network[j + a];
+    }
+  for (uint32_t j = 16 - a; j < 16; ++j)
+    {
+      nw[j] = 0;
+    }
+  for (uint32_t j = 0; j < 15; j++)
+    {
+      nw[j] = nw[j] << b;
+      nw[j] |= nw[j + 1] >> (8 - b);
+    }
+  nw[15] = nw[15] << b;
+  for (uint32_t j = 0; j < 16; j++)
+    {
+      nw[j] |= m_netTable[index].addr[j];
+    }
+
+  return Ipv6Address (nw);
+}
+
+Ipv6Address
+Ipv6AddressGeneratorImpl::NextAddress (const Ipv6Prefix prefix)
+{
+  NS_LOG_FUNCTION (this);
+
+  uint32_t index = PrefixToIndex (prefix);
+
+  uint8_t ad[16];
+  uint32_t a = m_netTable[index].shift / 8;
+  uint32_t b = m_netTable[index].shift % 8;
+  for (uint32_t j = 0; j < 16 - a; ++j)
+    {
+      ad[j] = m_netTable[index].network[j + a];
+    }
+  for (uint32_t j = 16 - a; j < 16; ++j)
+    {
+      ad[j] = 0;
+    }
+  for (uint32_t j = 0; j < 15; j++)
+    {
+      ad[j] = ad[j] << b;
+      ad[j] |= ad[j + 1] >> (8 - b);
+    }
+  ad[15] = ad[15] << b;
+  for (uint32_t j = 0; j < 16; j++)
+    {
+      ad[j] |= m_netTable[index].addr[j];
+    }
+  Ipv6Address addr = Ipv6Address (ad);
+
+  for (int32_t j = 15; j >= 0; j--)
+    {
+      if (m_netTable[index].addr[j] < 0xff)
+        {
+          ++m_netTable[index].addr[j];
+          break;
+        }
+      else
+        {
+          ++m_netTable[index].addr[j];
+        }
+    }
+
+  //
+  // Make a note that we've allocated this address -- used for address collision
+  // detection.
+  //
+  AddAllocated (addr);
+  return addr;
+}
+
+bool
+Ipv6AddressGeneratorImpl::AddAllocated (const Ipv6Address address)
+{
+  NS_LOG_FUNCTION (this << address);
+
+  uint8_t addr[16];
+  address.GetBytes (addr);
+
+  std::list<Entry>::iterator i;
+
+  for (i = m_entries.begin (); i != m_entries.end (); ++i)
+    {
+      NS_LOG_LOGIC ("examine entry: " << Ipv6Address ((*i).addrLow) <<
+                    " to " << Ipv6Address ((*i).addrHigh));
+      //
+      // First things first.  Is there an address collision -- that is, does the
+      // new address fall in a previously allocated block of addresses.
+      //
+      if (!(Ipv6Address (addr) < Ipv6Address ((*i).addrLow))
+          && ((Ipv6Address (addr) < Ipv6Address ((*i).addrHigh))
+              || (Ipv6Address (addr) == Ipv6Address ((*i).addrHigh))))
+        {
+          NS_LOG_LOGIC ("Ipv6AddressGeneratorImpl::Add(): Address Collision: " << Ipv6Address (addr));
+          if (!m_test)
+            {
+              NS_FATAL_ERROR ("Ipv6AddressGeneratorImpl::Add(): Address Collision: " << Ipv6Address (addr));
+            }
+          return false;
+        }
+      //
+      // If the new address is less than the lowest address in the current
+      // block and can't be merged into to the current block, then insert it
+      // as a new block before the current block.
+      //
+      uint8_t taddr[16];
+      for (uint32_t j = 0; j < 16; j++)
+        {
+          taddr[j] = (*i).addrLow[j];
+        }
+      taddr[15] -= 1;
+      if (Ipv6Address (addr) < Ipv6Address (taddr))
+        {
+          break;
+        }
+      //
+      // If the new address fits at the end of the block, look ahead to the next
+      // block and make sure it's not a collision there.  If we won't overlap,
+      // then just extend the current block by one address.  We expect that
+      // completely filled network ranges will be a fairly rare occurrence,
+      // so we don't worry about collapsing address range blocks.
+      //
+      for (uint32_t j = 0; j < 16; j++)
+        {
+          taddr[j] = (*i).addrLow[j];
+        }
+      taddr[15] += 1;
+      if (Ipv6Address (addr) == Ipv6Address (taddr))
+        {
+          std::list<Entry>::iterator j = i;
+          ++j;
+
+          if (j != m_entries.end ())
+            {
+              if (Ipv6Address (addr) == Ipv6Address ((*j).addrLow))
+                {
+                  NS_LOG_LOGIC ("Ipv6AddressGeneratorImpl::Add(): "
+                                "Address Collision: " << Ipv6Address (addr));
+                  if (!m_test)
+                    {
+                      NS_FATAL_ERROR ("Ipv6AddressGeneratorImpl::Add(): Address Collision: " << Ipv6Address (addr));
+                    }
+                  return false;
+                }
+            }
+
+          NS_LOG_LOGIC ("New addrHigh = " << Ipv6Address (addr));
+          for (uint32_t j = 0; j < 16; j++)
+            {
+              (*i).addrHigh[j] = addr[j];
+            }
+          return true;
+        }
+      //
+      // If we get here, we know that the next lower block of addresses
+      // couldn't have been extended to include this new address since the
+      // code immediately above would have been executed and that next lower
+      // block extended upward.  So we know it's safe to extend the current
+      // block down to includ the new address.
+      //
+      for (uint32_t j = 0; j < 16; j++)
+        {
+          taddr[j] = (*i).addrLow[j];
+        }
+      taddr[15] -= 1;
+      if ((Ipv6Address (addr) == Ipv6Address (taddr)))
+        {
+          NS_LOG_LOGIC ("New addrLow = " << Ipv6Address (addr));
+          for (uint32_t j = 0; j < 16; j++)
+            {
+              (*i).addrLow[j] = addr[j];
+            }
+          return true;
+        }
+    }
+
+  Entry entry;
+  for (uint32_t j = 0; j < 16; j++)
+    {
+      entry.addrLow[j] = entry.addrHigh[j] = addr[j];
+    }
+  m_entries.insert (i, entry);
+  return true;
+}
+
+void
+Ipv6AddressGeneratorImpl::TestMode (void)
+{
+  NS_LOG_FUNCTION (this);
+  m_test = true;
+}
+
+uint32_t
+Ipv6AddressGeneratorImpl::PrefixToIndex (Ipv6Prefix prefix) const
+{
+  //
+  // We've been given a prefix that has a higher order bit set for each bit of
+  // the network number.  In order to translate this prefix into an index,
+  // we just need to count the number of zero bits in the prefix.  We do this
+  // in a loop in which we shift the prefix right until we find the first
+  // nonzero bit.  This tells us the number of zero bits, and from this we
+  // infer the number of nonzero bits which is the number of bits in the prefix.
+  //
+  // We use the number of bits in the prefix as the number of bits in the
+  // network number and as the index into the network number state table.
+  //
+  uint8_t prefixBits[16];
+  prefix.GetBytes (prefixBits);
+
+  for (uint32_t i = 15; i >= 0; --i)
+    {
+      for (uint32_t j = 0; j < 8; ++j)
+        {
+          if (prefixBits[i] & 1)
+            {
+              uint32_t index = N_BITS - (15 - i) * 8 - j;
+              NS_ABORT_MSG_UNLESS (index > 0 && index < N_BITS, "Ip64AddressGenerator::PrefixToIndex(): Illegal Prefix");
+              return index;
+            }
+          prefixBits[i] >>= 1;
+        }
+    }
+  NS_ASSERT_MSG (false, "Ipv6AddressGenerator::PrefixToIndex(): Impossible");
+  return 0;
+}
+
+void
+Ipv6AddressGenerator::Init (
+  const Ipv6Address net,
+  const Ipv6Prefix prefix,
+  const Ipv6Address interfaceId)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  SimulationSingleton<Ipv6AddressGeneratorImpl>::Get ()
+  ->Init (net, prefix, interfaceId);
+}
+
+Ipv6Address
+Ipv6AddressGenerator::NextNetwork (const Ipv6Prefix prefix)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  return SimulationSingleton<Ipv6AddressGeneratorImpl>::Get ()
+         ->NextNetwork (prefix);
+}
+
+Ipv6Address
+Ipv6AddressGenerator::GetNetwork (const Ipv6Prefix prefix)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  return SimulationSingleton<Ipv6AddressGeneratorImpl>::Get ()
+         ->GetNetwork (prefix);
+}
+
+void
+Ipv6AddressGenerator::InitAddress (
+  const Ipv6Address interfaceId,
+  const Ipv6Prefix prefix)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  SimulationSingleton<Ipv6AddressGeneratorImpl>::Get ()
+  ->InitAddress (interfaceId, prefix);
+}
+
+Ipv6Address
+Ipv6AddressGenerator::GetAddress (const Ipv6Prefix prefix)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  return SimulationSingleton<Ipv6AddressGeneratorImpl>::Get ()
+         ->GetAddress (prefix);
+}
+
+Ipv6Address
+Ipv6AddressGenerator::NextAddress (const Ipv6Prefix prefix)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  return SimulationSingleton<Ipv6AddressGeneratorImpl>::Get ()
+         ->NextAddress (prefix);
+}
+
+void
+Ipv6AddressGenerator::Reset (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  return SimulationSingleton<Ipv6AddressGeneratorImpl>::Get ()
+         ->Reset ();
+}
+
+bool
+Ipv6AddressGenerator::AddAllocated (const Ipv6Address addr)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  return SimulationSingleton<Ipv6AddressGeneratorImpl>::Get ()
+         ->AddAllocated (addr);
+}
+
+void
+Ipv6AddressGenerator::TestMode (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  SimulationSingleton<Ipv6AddressGeneratorImpl>::Get ()
+  ->TestMode ();
+}
+
+} // namespace ns3
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet/model/ipv6-address-generator.h	Fri Dec 16 18:51:18 2011 +0100
@@ -0,0 +1,145 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 University of Washington
+ * Copyright (c) 2011 Atishay Jain
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef IPV6_ADDRESS_GENERATOR_H
+#define IPV6_ADDRESS_GENERATOR_H
+
+#include "ns3/ipv6-address.h"
+
+namespace ns3 {
+
+/**
+ * \ingroup address
+ *
+ * \brief This generator assigns addresses sequentially from a provided
+ * network address; used in topology code. It also keeps track of all
+ * addresses assigned to perform duplicate detection.
+ *
+ * Global unicast IPv6 addresses based on RFC 4291 definition:
+ *
+ *     |         n bits          |   m bits  |       128-n-m bits         |
+ *     +-------------------------+-----------+----------------------------+
+ *     | global routing prefix   | subnet ID |       interface ID         |
+ *     +-------------------------+-----------+----------------------------+
+ *
+ * In this class, the first two quantities (n + m) are what is called the
+ * 'net', and the 'prefix' defines the length in bits of (n + m).
+ *
+ * The way this is expected to be used is that, after initializing the
+ * network and interfaceId to a number, a user can call NextAddress ()
+ * repeatedly to obtain new interface IDs with the current network (for
+ * multiple addresses on the link) and can call NextNetwork () to increment
+ * the subnet ID.
+ *
+ * The interface ID is often an EUI-64 address derived from the MAC address,
+ * but can also be a pseudo-random value (RFC 3041).  This implementation
+ * does not generate EUI-64-based interface IDs.
+ */
+class Ipv6AddressGenerator
+{
+public:
+  /**
+   * \brief Initialise the base network and interfaceId for the generator
+   *
+   * The first call to NextAddress() or GetAddress() will return the
+   * value passed in.
+   *
+   * \param net The network for the base Ipv6Address
+   * \param prefix The prefix of the base Ipv6Address
+   * \param interfaceId The base interface ID used for initialization
+   */
+  static void Init (const Ipv6Address net, const Ipv6Prefix prefix,
+                    const Ipv6Address interfaceId = "::1");
+
+  /**
+   * \brief Get the next network acoording to the given Ipv6Prefix
+   *
+   * This operation is a pre-increment, meaning that the internal state
+   * is changed before returning the new network address.
+   *
+   * This also resets the interface ID to the base interface ID that was
+   * used for initialization.
+   *
+   * \param prefix The Ipv6Prefix used to set the next network
+   */
+  static Ipv6Address NextNetwork (const Ipv6Prefix prefix);
+
+  /**
+   * \brief Get the current network of the given Ipv6Prefix
+   *
+   * Does not change the internal state; this just peeks at the current
+   * network
+   *
+   * \param prefix The Ipv6Prefix for the current network
+   */
+  static Ipv6Address GetNetwork (const Ipv6Prefix prefix);
+
+  /**
+   * \brief Set the interfaceId for the given Ipv6Prefix
+   *
+   * \param interfaceId The interfaceId to set for the current Ipv6Prefix
+   * \param prefix The Ipv6Prefix whose address is to be set
+   */
+  static void InitAddress (const Ipv6Address interfaceId, const Ipv6Prefix prefix);
+
+  /**
+   * \brief Allocate the next Ipv6Address for the configured network and prefix
+   *
+   * This operation is a post-increment, meaning that the first address
+   * allocated will be the one that was initially configured.
+   * .
+   * \param prefix The Ipv6Prefix for the current network
+   */
+  static Ipv6Address NextAddress (const Ipv6Prefix prefix);
+
+  /**
+   * \brief Get the Ipv6Address that will be allocated upon NextAddress()
+   *
+   * Does not change the internal state; just is used to peek the next
+   * address that will be allocated upon NextAddress ()
+   *
+   * \param prefix The Ipv6Prefix for the current network
+   */
+  static Ipv6Address GetAddress (const Ipv6Prefix prefix);
+
+  /**
+   * \brief Reset the networks and Ipv6Address to zero
+   */
+  static void Reset (void);
+
+  /**
+   * \brief Add the Ipv6Address to the list of IPv6 entries
+   *
+   * Typically, this is used by external address allocators that want
+   * to make use of this class's ability to track duplicates.  AddAllocated
+   * is always called internally for any address generated by NextAddress()
+   *
+   * \param addr The Ipv6Address to be added to the list of Ipv6 entries
+   */
+  static bool AddAllocated (const Ipv6Address addr);
+
+  /**
+   * \brief Used to turn off fatal errors and assertions, for testing
+   */
+  static void TestMode (void);
+};
+
+}; // namespace ns3
+
+#endif /* IPV6_ADDRESS_GENERATOR_H */
--- a/src/internet/model/nsc-tcp-socket-impl.cc	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/model/nsc-tcp-socket-impl.cc	Fri Dec 16 18:51:18 2011 +0100
@@ -85,6 +85,7 @@
   : TcpSocket (sock), //copy the base class callbacks
     m_delAckMaxCount (sock.m_delAckMaxCount),
     m_delAckTimeout (sock.m_delAckTimeout),
+    m_noDelay (sock.m_noDelay),
     m_endPoint (0),
     m_node (sock.m_node),
     m_tcp (sock.m_tcp),
@@ -136,7 +137,7 @@
        * when DeAllocate is called, it will call into
        * Ipv4EndPointDemux::Deallocate which triggers
        * a delete of the associated endPoint which triggers
-       * in turn a call to the method ::Destroy below
+       * in turn a call to the method NscTcpSocketImpl::Destroy below
        * will will zero the m_endPoint field.
        */
       NS_ASSERT (m_endPoint != 0);
@@ -797,6 +798,18 @@
   return m_delAckMaxCount;
 }
 
+void
+NscTcpSocketImpl::SetTcpNoDelay (bool noDelay)
+{
+  m_noDelay = noDelay;
+}
+
+bool
+NscTcpSocketImpl::GetTcpNoDelay (void) const
+{
+  return m_noDelay;
+}
+
 void 
 NscTcpSocketImpl::SetPersistTimeout (Time timeout)
 {
--- a/src/internet/model/nsc-tcp-socket-impl.h	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/model/nsc-tcp-socket-impl.h	Fri Dec 16 18:51:18 2011 +0100
@@ -125,12 +125,15 @@
   virtual Time GetDelAckTimeout (void) const;
   virtual void SetDelAckMaxCount (uint32_t count);
   virtual uint32_t GetDelAckMaxCount (void) const;
+  virtual void SetTcpNoDelay (bool noDelay);
+  virtual bool GetTcpNoDelay (void) const;
   virtual void SetPersistTimeout (Time timeout);
   virtual Time GetPersistTimeout (void) const;
 
   enum Socket::SocketErrno GetNativeNs3Errno (int err) const;
   uint32_t m_delAckMaxCount;
   Time m_delAckTimeout;
+  bool m_noDelay;
 
   Ipv4EndPoint *m_endPoint;
   Ptr<Node> m_node;
--- a/src/internet/model/rtt-estimator.cc	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/model/rtt-estimator.cc	Fri Dec 16 18:51:18 2011 +0100
@@ -54,7 +54,7 @@
                    MakeTimeChecker ())
     .AddAttribute ("MinRTO", 
                    "Minimum retransmit timeout value",
-                   TimeValue (Seconds (0.2)),
+                   TimeValue (Seconds (0.2)), // RFC2988 says min RTO=1 sec, but Linux uses 200ms. See http://www.postel.org/pipermail/end2end-interest/2004-November/004402.html
                    MakeTimeAccessor (&RttEstimator::SetMinRto,
                                      &RttEstimator::GetMinRto),
                    MakeTimeChecker ())
--- a/src/internet/model/tcp-header.cc	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/model/tcp-header.cc	Fri Dec 16 18:51:18 2011 +0100
@@ -197,6 +197,14 @@
         {
           os<<" URG ";
         }
+      if((m_flags & ECE) != 0)
+        {
+          os<<" ECE ";
+        }
+      if((m_flags & CWR) != 0)
+        {
+          os<<" CWR ";
+        }
       os<<"]";
     }
   os<<" Seq="<<m_sequenceNumber<<" Ack="<<m_ackNumber<<" Win="<<m_windowSize;
--- a/src/internet/model/tcp-header.h	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/model/tcp-header.h	Fri Dec 16 18:51:18 2011 +0100
@@ -134,7 +134,7 @@
                            uint8_t protocol);
 
   typedef enum { NONE = 0, FIN = 1, SYN = 2, RST = 4, PSH = 8, ACK = 16, 
-                 URG = 32} Flags_t;
+                 URG = 32, ECE = 64, CWR = 128} Flags_t;
 
   static TypeId GetTypeId (void);
   virtual TypeId GetInstanceTypeId (void) const;
--- a/src/internet/model/tcp-l4-protocol.cc	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/model/tcp-l4-protocol.cc	Fri Dec 16 18:51:18 2011 +0100
@@ -137,10 +137,6 @@
 TcpL4Protocol::DoDispose (void)
 {
   NS_LOG_FUNCTION_NOARGS ();
-  for (std::vector<Ptr<TcpSocketBase> >::iterator i = m_sockets.begin (); i != m_sockets.end (); i++)
-    {
-      *i = 0;
-    }
   m_sockets.clear ();
 
   if (m_endPoints != 0)
@@ -167,7 +163,6 @@
   socket->SetNode (m_node);
   socket->SetTcp (this);
   socket->SetRtt (rtt);
-  m_sockets.push_back (socket);
   return socket;
 }
 
--- a/src/internet/model/tcp-newreno.cc	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/model/tcp-newreno.cc	Fri Dec 16 18:51:18 2011 +0100
@@ -40,6 +40,14 @@
   static TypeId tid = TypeId ("ns3::TcpNewReno")
     .SetParent<TcpSocketBase> ()
     .AddConstructor<TcpNewReno> ()
+    .AddAttribute ("ReTxThreshold", "Threshold for fast retransmit",
+                    UintegerValue (3),
+                    MakeUintegerAccessor (&TcpNewReno::m_retxThresh),
+                    MakeUintegerChecker<uint32_t> ())
+    .AddAttribute ("LimitedTransmit", "Enable limited transmit",
+		    BooleanValue (false),
+		    MakeBooleanAccessor (&TcpNewReno::m_limitedTx),
+		    MakeBooleanChecker ())
     .AddTraceSource ("CongestionWindow",
                      "The TCP connection's congestion window",
                      MakeTraceSourceAccessor (&TcpNewReno::m_cWnd))
@@ -47,7 +55,10 @@
   return tid;
 }
 
-TcpNewReno::TcpNewReno (void) : m_inFastRec (false)
+TcpNewReno::TcpNewReno (void)
+  : m_retxThresh (3), // mute valgrind, actual value set by the attribute system
+    m_inFastRec (false),
+    m_limitedTx (false) // mute valgrind, actual value set by the attribute system
 {
   NS_LOG_FUNCTION (this);
 }
@@ -57,7 +68,9 @@
     m_cWnd (sock.m_cWnd),
     m_ssThresh (sock.m_ssThresh),
     m_initialCWnd (sock.m_initialCWnd),
-    m_inFastRec (false)
+    m_retxThresh (sock.m_retxThresh),
+    m_inFastRec (false),
+    m_limitedTx (sock.m_limitedTx)
 {
   NS_LOG_FUNCTION (this);
   NS_LOG_LOGIC ("Invoked the copy constructor");
@@ -111,6 +124,7 @@
   // Check for exit condition of fast recovery
   if (m_inFastRec && seq < m_recover)
     { // Partial ACK, partial window deflation (RFC2582 sec.3 bullet #5 paragraph 3)
+      m_cWnd -= seq - m_txBuffer.HeadSequence ();
       m_cWnd += m_segmentSize;  // increase cwnd
       NS_LOG_INFO ("Partial ACK in fast recovery: cwnd set to " << m_cWnd);
       TcpSocketBase::NewAck (seq); // update m_nextTxSequence and send new data if allowed by window
@@ -148,7 +162,7 @@
 TcpNewReno::DupAck (const TcpHeader& t, uint32_t count)
 {
   NS_LOG_FUNCTION (this << count);
-  if (count == 3 && !m_inFastRec)
+  if (count == m_retxThresh && !m_inFastRec)
     { // triple duplicate ack triggers fast retransmit (RFC2582 sec.3 bullet #1)
       m_ssThresh = std::max (2 * m_segmentSize, BytesInFlight () / 2);
       m_cWnd = m_ssThresh + 3 * m_segmentSize;
@@ -163,6 +177,12 @@
       m_cWnd += m_segmentSize;
       NS_LOG_INFO ("Dupack in fast recovery mode. Increase cwnd to " << m_cWnd);
       SendPendingData (m_connected);
+    }
+  else if (!m_inFastRec && m_limitedTx && m_txBuffer.SizeFromSequence (m_nextTxSequence) > 0)
+    { // RFC3042 Limited transmit: Send a new packet for each duplicated ACK before fast retransmit
+      NS_LOG_INFO ("Limited transmit");
+      uint32_t sz = SendDataPacket (m_nextTxSequence, m_segmentSize, true);
+      m_nextTxSequence += sz;                    // Advance next tx sequence
     };
 }
 
@@ -176,8 +196,8 @@
 
   // If erroneous timeout in closed/timed-wait state, just return
   if (m_state == CLOSED || m_state == TIME_WAIT) return;
-  // If all data are received, just return
-  if (m_txBuffer.HeadSequence () >= m_nextTxSequence) return;
+  // If all data are received (non-closing socket and nothing to send), just return
+  if (m_state <= ESTABLISHED && m_txBuffer.HeadSequence () >= m_highTxMark) return;
 
   // According to RFC2581 sec.3.1, upon RTO, ssthresh is set to half of flight
   // size and cwnd is set to 1*MSS, then the lost packet is retransmitted and
--- a/src/internet/model/tcp-newreno.h	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/model/tcp-newreno.h	Fri Dec 16 18:51:18 2011 +0100
@@ -69,7 +69,9 @@
   uint32_t               m_ssThresh;     //< Slow Start Threshold
   uint32_t               m_initialCWnd;  //< Initial cWnd value
   SequenceNumber32       m_recover;      //< Previous highest Tx seqnum for fast recovery
+  uint32_t               m_retxThresh;   //< Fast Retransmit threshold
   bool                   m_inFastRec;    //< currently in fast recovery
+  bool                   m_limitedTx;    //< perform limited transmit
 };
 
 } // namespace ns3
--- a/src/internet/model/tcp-reno.cc	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/model/tcp-reno.cc	Fri Dec 16 18:51:18 2011 +0100
@@ -40,6 +40,10 @@
   static TypeId tid = TypeId ("ns3::TcpReno")
     .SetParent<TcpSocketBase> ()
     .AddConstructor<TcpReno> ()
+    .AddAttribute ("ReTxThreshold", "Threshold for fast retransmit",
+                    UintegerValue (3),
+                    MakeUintegerAccessor (&TcpReno::m_retxThresh),
+                    MakeUintegerChecker<uint32_t> ())
     .AddTraceSource ("CongestionWindow",
                      "The TCP connection's congestion window",
                      MakeTraceSourceAccessor (&TcpReno::m_cWnd))
@@ -47,7 +51,7 @@
   return tid;
 }
 
-TcpReno::TcpReno (void) : m_inFastRec (false)
+TcpReno::TcpReno (void) : m_retxThresh (3), m_inFastRec (false)
 {
   NS_LOG_FUNCTION (this);
 }
@@ -57,6 +61,7 @@
     m_cWnd (sock.m_cWnd),
     m_ssThresh (sock.m_ssThresh),
     m_initialCWnd (sock.m_initialCWnd),
+    m_retxThresh (sock.m_retxThresh),
     m_inFastRec (false)
 {
   NS_LOG_FUNCTION (this);
@@ -141,7 +146,7 @@
 TcpReno::DupAck (const TcpHeader& t, uint32_t count)
 {
   NS_LOG_FUNCTION (this << "t " << count);
-  if (count == 3 && !m_inFastRec)
+  if (count == m_retxThresh && !m_inFastRec)
     { // triple duplicate ack triggers fast retransmit (RFC2581, sec.3.2)
       m_ssThresh = std::max (2 * m_segmentSize, BytesInFlight () / 2);
       m_cWnd = m_ssThresh + 3 * m_segmentSize;
@@ -166,8 +171,8 @@
 
   // If erroneous timeout in closed/timed-wait state, just return
   if (m_state == CLOSED || m_state == TIME_WAIT) return;
-  // If all data are received, just return
-  if (m_txBuffer.HeadSequence () >= m_nextTxSequence) return;
+  // If all data are received (non-closing socket and nothing to send), just return
+  if (m_state <= ESTABLISHED && m_txBuffer.HeadSequence () >= m_highTxMark) return;
 
   // According to RFC2581 sec.3.1, upon RTO, ssthresh is set to half of flight
   // size and cwnd is set to 1*MSS, then the lost packet is retransmitted and
--- a/src/internet/model/tcp-reno.h	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/model/tcp-reno.h	Fri Dec 16 18:51:18 2011 +0100
@@ -70,6 +70,7 @@
   TracedValue<uint32_t>  m_cWnd;         //< Congestion window
   uint32_t               m_ssThresh;     //< Slow Start Threshold
   uint32_t               m_initialCWnd;  //< Initial cWnd value
+  uint32_t               m_retxThresh;   //< Fast Retransmit threshold
   bool                   m_inFastRec;    //< currently in fast recovery
 };
 
--- a/src/internet/model/tcp-rx-buffer.cc	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/model/tcp-rx-buffer.cc	Fri Dec 16 18:51:18 2011 +0100
@@ -102,7 +102,7 @@
   m_nextRxSeq++;
 }
 
-// Return the highest sequence number that this TcpRxBuffer can accept
+// Return the lowest sequence number that this TcpRxBuffer cannot accept
 SequenceNumber32
 TcpRxBuffer::MaxRxSequence (void) const
 {
--- a/src/internet/model/tcp-socket-base.cc	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/model/tcp-socket-base.cc	Fri Dec 16 18:51:18 2011 +0100
@@ -1,5 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
+ * Copyright (c) 2007 Georgia Tech Research Corporation
  * Copyright (c) 2010 Adrian Sai-wah Tam
  *
  * This program is free software; you can redistribute it and/or modify
@@ -33,6 +34,7 @@
 #include "ns3/simulator.h"
 #include "ns3/packet.h"
 #include "ns3/uinteger.h"
+#include "ns3/double.h"
 #include "ns3/trace-source-accessor.h"
 #include "tcp-socket-base.h"
 #include "tcp-l4-protocol.h"
@@ -58,6 +60,15 @@
 //                   EnumValue (CLOSED),
 //                   MakeEnumAccessor (&TcpSocketBase::m_state),
 //                   MakeEnumChecker (CLOSED, "Closed"))
+    .AddAttribute ("MaxSegLifetime",
+                   "Maximum segment lifetime in seconds, use for TIME_WAIT state transition to CLOSED state",
+                   DoubleValue (120), /* RFC793 says MSL=2 minutes*/
+                   MakeDoubleAccessor (&TcpSocketBase::m_msl),
+                   MakeDoubleChecker<double> (0))
+    .AddAttribute ("MaxWindowSize", "Max size of advertised window",
+                   UintegerValue (65535),
+                   MakeUintegerAccessor (&TcpSocketBase::m_maxWinSize),
+                   MakeUintegerChecker<uint16_t> ())
     .AddTraceSource ("RTO",
                      "Retransmission timeout",
                      MakeTraceSourceAccessor (&TcpSocketBase::m_rto))
@@ -109,7 +120,8 @@
     m_dupAckCount (sock.m_dupAckCount),
     m_delAckCount (0),
     m_delAckMaxCount (sock.m_delAckMaxCount),
-    m_cnCount (sock.m_cnCount),
+    m_noDelay (sock.m_noDelay),
+    m_cnRetries (sock.m_cnRetries),
     m_delAckTimeout (sock.m_delAckTimeout),
     m_persistTimeout (sock.m_persistTimeout),
     m_cnTimeout (sock.m_cnTimeout),
@@ -128,7 +140,9 @@
     m_shutdownSend (sock.m_shutdownSend),
     m_shutdownRecv (sock.m_shutdownRecv),
     m_connected (sock.m_connected),
+    m_msl (sock.m_msl),
     m_segmentSize (sock.m_segmentSize),
+    m_maxWinSize (sock.m_maxWinSize),
     m_rWnd (sock.m_rWnd)
 {
   NS_LOG_FUNCTION (this);
@@ -224,6 +238,7 @@
       m_errno = ERROR_ADDRNOTAVAIL;
       return -1;
     }
+  m_tcp->m_sockets.push_back (this);
   return SetupCallback ();
 }
 
@@ -243,39 +258,25 @@
   if (ipv4 == Ipv4Address::GetAny () && port == 0)
     {
       m_endPoint = m_tcp->Allocate ();
-      if (0 == m_endPoint)
-        {
-	  m_errno = ERROR_ADDRNOTAVAIL;
-          return -1;
-	}
     }
   else if (ipv4 == Ipv4Address::GetAny () && port != 0)
     {
       m_endPoint = m_tcp->Allocate (port);
-      if (0 == m_endPoint)
-        {
-          m_errno = ERROR_ADDRINUSE;
-          return -1;
-        }
     }
   else if (ipv4 != Ipv4Address::GetAny () && port == 0)
     {
       m_endPoint = m_tcp->Allocate (ipv4);
-      if (0 == m_endPoint)
-        {
-	  m_errno = ERROR_ADDRNOTAVAIL;
-	  return -1;
-        }
     }
   else if (ipv4 != Ipv4Address::GetAny () && port != 0)
     {
       m_endPoint = m_tcp->Allocate (ipv4, port);
-      if (0 == m_endPoint)
-        {
-          m_errno = ERROR_ADDRINUSE;
-          return -1;
-        }
     }
+  if (0 == m_endPoint)
+    {
+      m_errno = port ? ERROR_ADDRINUSE : ERROR_ADDRNOTAVAIL;
+      return -1;
+    }
+  m_tcp->m_sockets.push_back (this);
   NS_LOG_LOGIC ("TcpSocketBase " << this << " got an endpoint: " << m_endPoint);
 
   return SetupCallback ();
@@ -307,6 +308,10 @@
       return -1;
     }
 
+  // Re-initialize parameters in case this socket is being reused after CLOSE
+  m_rtt->Reset ();
+  m_cnCount = m_cnRetries;
+
   // DoConnect() will do state-checking and send a SYN packet
   return DoConnect ();
 }
@@ -437,14 +442,14 @@
   // Null packet means no data to read, and an empty packet indicates EOF
   if (packet != 0 && packet->GetSize () != 0)
     {
-      SocketAddressTag tag;
-      bool found;
-      found = packet->PeekPacketTag (tag);
-      NS_ASSERT (found);
-      //cast found to void , to suppress 'found' set but not used compiler warning
-      //in optimized builds
-      (void) found;
-      fromAddress = tag.GetAddress ();
+      if (m_endPoint != 0)
+        {
+          fromAddress = InetSocketAddress (m_endPoint->GetPeerAddress (), m_endPoint->GetPeerPort ());
+        }
+      else
+        {
+          fromAddress = InetSocketAddress (Ipv4Address::GetZero (), 0);
+        }
     }
   return packet;
 }
@@ -531,8 +536,8 @@
   else if (m_state != TIME_WAIT)
     { // In states SYN_RCVD, ESTABLISHED, FIN_WAIT_1, FIN_WAIT_2, and CLOSING, an connection
       // exists. We send RST, tear down everything, and close this socket.
+      SendRST ();
       CloseAndNotify ();
-      SendRST ();
     }
   return 0;
 }
@@ -561,8 +566,8 @@
     case SYN_SENT:
     case CLOSING:
       // Send RST if application closes in SYN_SENT and CLOSING
+      SendRST ();
       CloseAndNotify ();
-      SendRST ();
       break;
     case LISTEN:
     case LAST_ACK:
@@ -587,30 +592,31 @@
   NS_LOG_FUNCTION (this);
 
   if (!m_closeNotified) NotifyNormalClose ();
+  if (m_state != TIME_WAIT) DeallocateEndPoint ();
   m_closeNotified = true;
   NS_LOG_INFO (TcpStateName[m_state] << " -> CLOSED");
+  CancelAllTimers ();
   m_state = CLOSED;
-  DeallocateEndPoint ();
 }
 
 
-/** Tell if a sequence number is out side the range that my rx buffer can
+/** Tell if a sequence number range is out side the range that my rx buffer can
     accpet */
 bool
-TcpSocketBase::OutOfRange (SequenceNumber32 s) const
+TcpSocketBase::OutOfRange (SequenceNumber32 head, SequenceNumber32 tail) const
 {
   if (m_state == LISTEN || m_state == SYN_SENT || m_state == SYN_RCVD)
     { // Rx buffer in these states are not initialized.
       return false;
     }
-  if (m_state == LAST_ACK || m_state == CLOSING)
+  if (m_state == LAST_ACK || m_state == CLOSING || m_state == CLOSE_WAIT)
     { // In LAST_ACK and CLOSING states, it only wait for an ACK and the
       // sequence number must equals to m_rxBuffer.NextRxSequence ()
-      return (m_rxBuffer.NextRxSequence () != s);
+      return (m_rxBuffer.NextRxSequence () != head);
     };
 
   // In all other cases, check if the sequence number is in range
-  return (m_rxBuffer.MaxRxSequence () < s || m_rxBuffer.NextRxSequence () > s);
+  return (tail < m_rxBuffer.NextRxSequence () || m_rxBuffer.MaxRxSequence () <= head);
 }
 
 /** Function called by the L3 protocol when it received a packet to pass on to
@@ -620,6 +626,16 @@
 TcpSocketBase::ForwardUp (Ptr<Packet> packet, Ipv4Header header, uint16_t port,
                           Ptr<Ipv4Interface> incomingInterface)
 {
+  DoForwardUp (packet, header, port, incomingInterface);
+}
+
+/** The real function to handle the incoming packet from lower layers. This is
+    wrapped by ForwardUp() so that this function can be overloaded by daughter
+    classes. */
+void
+TcpSocketBase::DoForwardUp (Ptr<Packet> packet, Ipv4Header header, uint16_t port,
+                            Ptr<Ipv4Interface> incomingInterface)
+{
   NS_LOG_LOGIC ("Socket " << this << " forward up " <<
                 m_endPoint->GetPeerAddress () <<
                 ":" << m_endPoint->GetPeerPort () <<
@@ -635,6 +651,7 @@
     { 
       EstimateRtt (tcpHeader);
     }
+  ReadOptions (tcpHeader);
 
   // Update Rx window size, i.e. the flow control window
   if (m_rWnd.Get () == 0 && tcpHeader.GetWindowSize () != 0)
@@ -644,13 +661,20 @@
     }
   m_rWnd = tcpHeader.GetWindowSize ();
 
-  // Discard out of range packets
-  if (OutOfRange (tcpHeader.GetSequenceNumber ()))
+  // Discard fully out of range data packets
+  if (packet->GetSize () &&
+      OutOfRange (tcpHeader.GetSequenceNumber (), tcpHeader.GetSequenceNumber () + packet->GetSize ()))
     {
       NS_LOG_LOGIC ("At state " << TcpStateName[m_state] <<
-                    " received packet of seq " << tcpHeader.GetSequenceNumber () <<
-                    " out of range [" << m_rxBuffer.NextRxSequence () << ":" <<
-                    m_rxBuffer.MaxRxSequence () << "]");
+                    " received packet of seq [" << tcpHeader.GetSequenceNumber () <<
+                    ":" << tcpHeader.GetSequenceNumber () + packet->GetSize() <<
+                    ") out of range [" << m_rxBuffer.NextRxSequence () << ":" <<
+                    m_rxBuffer.MaxRxSequence () << ")");
+      // Acknowledgement should be sent for all unacceptable packets (RFC793, p.69)
+      if (m_state == ESTABLISHED && !(tcpHeader.GetFlags () & TcpHeader::RST))
+        {
+          SendEmptyPacket (TcpHeader::ACK);
+        }
       return;
     }
 
@@ -670,8 +694,16 @@
     case CLOSED:
       // Send RST if the incoming packet is not a RST
       if ((tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG)) != TcpHeader::RST)
-        {
-          SendRST ();
+        { // Since m_endPoint is not configured yet, we cannot use SendRST here
+          TcpHeader h;
+          h.SetFlags (TcpHeader::RST);
+          h.SetSequenceNumber (m_nextTxSequence);
+          h.SetAckNumber (m_rxBuffer.NextRxSequence ());
+          h.SetSourcePort (tcpHeader.GetDestinationPort ());
+          h.SetDestinationPort (tcpHeader.GetSourcePort ());
+          h.SetWindowSize (AdvertisedWindowSize ());
+          AddOptions (h);
+          m_tcp->SendPacket (Create<Packet> (), h, header.GetDestination (), header.GetSource (), m_boundnetdevice);
         }
       break;
     case SYN_SENT:
@@ -733,12 +765,12 @@
     }
   else
     { // Received RST or the TCP flags is invalid, in either case, terminate this socket
-      CloseAndNotify ();
       if (tcpflags != TcpHeader::RST)
         { // this must be an invalid flag, send reset
           NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
           SendRST ();
         }
+      CloseAndNotify ();
     }
 }
 
@@ -818,6 +850,7 @@
       m_state = ESTABLISHED;
       m_connected = true;
       m_retxEvent.Cancel ();
+      m_delAckCount = m_delAckMaxCount;
       ReceivedData (packet, tcpHeader);
       Simulator::ScheduleNow (&TcpSocketBase::ConnectionSucceeded, this);
     }
@@ -828,6 +861,7 @@
     { // Received SYN, move to SYN_RCVD state and respond with SYN+ACK
       NS_LOG_INFO ("SYN_SENT -> SYN_RCVD");
       m_state = SYN_RCVD;
+      m_cnCount = m_cnRetries;
       m_rxBuffer.SetNextRxSequence (tcpHeader.GetSequenceNumber () + SequenceNumber32 (1));
       SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK);
     }
@@ -842,21 +876,20 @@
       m_highTxMark = ++m_nextTxSequence;
       m_txBuffer.SetHeadSequence (m_nextTxSequence);
       SendEmptyPacket (TcpHeader::ACK);
-      if (GetTxAvailable () > 0)
-        {
-          NotifySend (GetTxAvailable ());
-        }
       SendPendingData (m_connected);
       Simulator::ScheduleNow (&TcpSocketBase::ConnectionSucceeded, this);
+      // Always respond to first data packet to speed up the connection.
+      // Remove to get the behaviour of old NS-3 code.
+      m_delAckCount = m_delAckMaxCount;
     }
   else
     { // Other in-sequence input
-      CloseAndNotify ();
       if (tcpflags != TcpHeader::RST)
         { // When (1) rx of FIN+ACK; (2) rx of FIN; (3) rx of bad flags
-          NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
+          NS_LOG_LOGIC ("Illegal flag " << std::hex << static_cast<uint32_t>(tcpflags) << std::dec << " received. Reset packet is sent.");
           SendRST ();
         }
+      CloseAndNotify ();
     }
 }
 
@@ -882,12 +915,18 @@
       m_retxEvent.Cancel ();
       m_highTxMark = ++m_nextTxSequence;
       m_txBuffer.SetHeadSequence (m_nextTxSequence);
-      m_endPoint->SetPeer (m_endPoint->GetPeerAddress (), m_endPoint->GetPeerPort ());
+      m_endPoint->SetPeer (InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
+                           InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
       // Always respond to first data packet to speed up the connection.
       // Remove to get the behaviour of old NS-3 code.
       m_delAckCount = m_delAckMaxCount;
       ReceivedAck (packet, tcpHeader);
       NotifyNewConnectionCreated (this, fromAddress);
+      // As this connection is established, the socket is available to send data now
+      if (GetTxAvailable () > 0)
+        {
+          NotifySend (GetTxAvailable ());
+        }
     }
   else if (tcpflags == TcpHeader::SYN)
     { // Probably the peer lost my SYN+ACK
@@ -902,18 +941,21 @@
           m_retxEvent.Cancel ();
           m_highTxMark = ++m_nextTxSequence;
           m_txBuffer.SetHeadSequence (m_nextTxSequence);
-          m_endPoint->SetPeer (m_endPoint->GetPeerAddress (), m_endPoint->GetPeerPort ());
+          m_endPoint->SetPeer (InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
+                               InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
           PeerClose (packet, tcpHeader);
         }
     }
   else
     { // Other in-sequence input
-      CloseAndNotify ();
       if (tcpflags != TcpHeader::RST)
         { // When (1) rx of SYN+ACK; (2) rx of FIN; (3) rx of bad flags
           NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
+          m_endPoint->SetPeer (InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
+                               InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
           SendRST ();
         }
+      CloseAndNotify ();
     }
 }
 
@@ -954,12 +996,12 @@
     }
   else
     { // This is a RST or bad flags
-      CloseAndNotify ();
       if (tcpflags != TcpHeader::RST)
         {
           NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
           SendRST ();
         }
+      CloseAndNotify ();
       return;
     }
 
@@ -973,18 +1015,12 @@
           if (m_txBuffer.Size () == 0 &&
               tcpHeader.GetAckNumber () == m_highTxMark + SequenceNumber32 (1))
             { // This ACK corresponds to the FIN sent
-              NS_LOG_INFO ("CLOSING -> TIME_WAIT");
-              m_state = TIME_WAIT;
-              CancelAllTimers ();
+              TimeWait ();
             }
         }
       else if (m_state == FIN_WAIT_2)
         {
-          NS_LOG_INFO ("FIN_WAIT_2 -> TIME_WAIT");
-          m_state = TIME_WAIT;
-          CancelAllTimers ();
-          // TODO: In TIME_WAIT, we supposed to move to CLOSED after 2*MSL time
-          // but this move is not yet implemeneted. Is this necessary?
+          TimeWait ();
         };
       SendEmptyPacket (TcpHeader::ACK);
       if (!m_shutdownRecv) NotifyDataRecv ();
@@ -1004,17 +1040,12 @@
     {
       if (tcpHeader.GetSequenceNumber () == m_rxBuffer.NextRxSequence ())
         { // This ACK corresponds to the FIN sent
-          NS_LOG_INFO ("CLOSING -> TIME_WAIT");
-          m_state = TIME_WAIT;
-          CancelAllTimers ();
-          // TODO: In TIME_WAIT, we supposed to move to CLOSED after 2*MSL time
-          // but this move is not yet implemeneted. Is this necessary?
+          TimeWait ();
         }
     }
   else
     { // CLOSING state means simultaneous close, i.e. no one is sending data to
       // anyone. If anything other than ACK is received, respond with a reset.
-      CloseAndNotify ();
       if (tcpflags == TcpHeader::FIN || tcpflags == (TcpHeader::FIN | TcpHeader::ACK))
         { // FIN from the peer as well. We can close immediately.
           SendEmptyPacket (TcpHeader::ACK);
@@ -1024,6 +1055,7 @@
           NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
           SendRST ();
         }
+      CloseAndNotify ();
     }
 }
 
@@ -1057,9 +1089,9 @@
     }
   else
     { // Received a SYN or SYN+ACK or bad flags
-      CloseAndNotify ();
       NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
       SendRST ();
+      CloseAndNotify ();
     }
 }
 
@@ -1119,7 +1151,7 @@
       // until all its existing data are pushed into the TCP socket, then call Close()
       // explicitly.
       NS_LOG_LOGIC ("TCP " << this << " calling NotifyNormalClose");
-      if (!m_closeNotified) NotifyNormalClose ();
+      NotifyNormalClose ();
       m_closeNotified = true;
     }
   if (m_shutdownSend)
@@ -1146,6 +1178,12 @@
   NS_LOG_FUNCTION (this);
   m_node = 0;
   m_endPoint = 0;
+  std::vector<Ptr<TcpSocketBase> >::iterator it
+    = std::find (m_tcp->m_sockets.begin (), m_tcp->m_sockets.end (), this);
+  if (it != m_tcp->m_sockets.end ())
+    {
+      m_tcp->m_sockets.erase (it);
+    }
   m_tcp = 0;
   NS_LOG_LOGIC (this << " Cancelled ReTxTimeout event which was set to expire at " <<
                 (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
@@ -1181,17 +1219,27 @@
   header.SetSourcePort (m_endPoint->GetLocalPort ());
   header.SetDestinationPort (m_endPoint->GetPeerPort ());
   header.SetWindowSize (AdvertisedWindowSize ());
-  m_tcp->SendPacket (p, header, m_endPoint->GetLocalAddress (), m_endPoint->GetPeerAddress (), m_boundnetdevice);
+  AddOptions (header);
   m_rto = m_rtt->RetransmitTimeout ();
   bool hasSyn = flags & TcpHeader::SYN;
   bool hasFin = flags & TcpHeader::FIN;
   bool isAck = flags == TcpHeader::ACK;
   if (hasSyn)
-    { // Exponential backoff of connection time out
-      m_rto = m_cnTimeout;
-      m_cnTimeout = m_cnTimeout + m_cnTimeout;
-      m_cnCount--;
+    {
+      if (m_cnCount == 0)
+        { // No more connection retries, give up
+          NS_LOG_LOGIC ("Connection failed.");
+          CloseAndNotify ();
+          return;
+        }
+      else
+        { // Exponential backoff of connection time out
+          int backoffCount = 0x1 << (m_cnRetries - m_cnCount);
+          m_rto = m_cnTimeout * backoffCount;
+          m_cnCount--;
+        }
     }
+  m_tcp->SendPacket (p, header, m_endPoint->GetLocalAddress (), m_endPoint->GetPeerAddress (), m_boundnetdevice);
   if (flags & TcpHeader::ACK)
     { // If sending an ACK, cancel the delay ACK as well
       m_delAckEvent.Cancel ();
@@ -1216,7 +1264,7 @@
   DeallocateEndPoint ();
 }
 
-/** Deallocate the end point the cancel all the timers */
+/** Deallocate the end point and cancel all the timers */
 void
 TcpSocketBase::DeallocateEndPoint (void)
 {
@@ -1225,6 +1273,12 @@
       m_endPoint->SetDestroyCallback (MakeNullCallback<void> ());
       m_tcp->DeAllocate (m_endPoint);
       m_endPoint = 0;
+      std::vector<Ptr<TcpSocketBase> >::iterator it
+        = std::find (m_tcp->m_sockets.begin (), m_tcp->m_sockets.end (), this);
+      if (it != m_tcp->m_sockets.end ())
+        {
+          m_tcp->m_sockets.erase (it);
+        }
       CancelAllTimers ();
     }
 }
@@ -1272,10 +1326,12 @@
                                 InetSocketAddress::ConvertFrom (toAddress).GetPort (),
                                 InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
                                 InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
+  m_tcp->m_sockets.push_back (this);
 
   // Change the cloned socket from LISTEN state to SYN_RCVD
   NS_LOG_INFO ("LISTEN -> SYN_RCVD");
   m_state = SYN_RCVD;
+  m_cnCount = m_cnRetries;
   SetupCallback ();
   // Set the sequence number and send SYN+ACK
   m_rxBuffer.SetNextRxSequence (h.GetSequenceNumber () + SequenceNumber32 (1));
@@ -1287,10 +1343,73 @@
 { // Wrapper to protected function NotifyConnectionSucceeded() so that it can
   // be called as a scheduled event
   NotifyConnectionSucceeded ();
+  // The if-block below was moved from ProcessSynSent() to here because we need
+  // to invoke the NotifySend() only after NotifyConnectionSucceeded() to
+  // reflect the behaviour in the real world.
+  if (GetTxAvailable () > 0)
+    {
+      NotifySend (GetTxAvailable ());
+    }
 }
 
-// Send as much pending data as possible according to the Tx window. Note that
-// this function did not implement the PSH flag
+/** Extract at most maxSize bytes from the TxBuffer at sequence seq, add the
+    TCP header, and send to TcpL4Protocol */
+uint32_t
+TcpSocketBase::SendDataPacket (SequenceNumber32 seq, uint32_t maxSize, bool withAck)
+{
+  NS_LOG_FUNCTION (this << seq << maxSize << withAck);
+
+  Ptr<Packet> p = m_txBuffer.CopyFromSequence (maxSize, seq);
+  uint32_t sz = p->GetSize (); // Size of packet
+  uint8_t flags = withAck ? TcpHeader::ACK : 0;
+  uint32_t remainingData = m_txBuffer.SizeFromSequence (seq + SequenceNumber32 (sz));
+  if (m_closeOnEmpty && (remainingData == 0))
+    {
+      flags |= TcpHeader::FIN;
+      if (m_state == ESTABLISHED)
+        { // On active close: I am the first one to send FIN
+          NS_LOG_INFO ("ESTABLISHED -> FIN_WAIT_1");
+          m_state = FIN_WAIT_1;
+        }
+      else if (m_state == CLOSE_WAIT)
+        { // On passive close: Peer sent me FIN already
+          NS_LOG_INFO ("CLOSE_WAIT -> LAST_ACK");
+          m_state = LAST_ACK;
+        }
+    }
+  TcpHeader header;
+  header.SetFlags (flags);
+  header.SetSequenceNumber (seq);
+  header.SetAckNumber (m_rxBuffer.NextRxSequence ());
+  header.SetSourcePort (m_endPoint->GetLocalPort ());
+  header.SetDestinationPort (m_endPoint->GetPeerPort ());
+  header.SetWindowSize (AdvertisedWindowSize ());
+  AddOptions (header);
+  if (m_retxEvent.IsExpired () )
+    { // Schedule retransmit
+      m_rto = m_rtt->RetransmitTimeout ();
+      NS_LOG_LOGIC (this << " SendDataPacket Schedule ReTxTimeout at time " <<
+                    Simulator::Now ().GetSeconds () << " to expire at time " <<
+                    (Simulator::Now () + m_rto.Get ()).GetSeconds () );
+      m_retxEvent = Simulator::Schedule (m_rto, &TcpSocketBase::ReTxTimeout, this);
+    }
+  NS_LOG_LOGIC ("Send packet via TcpL4Protocol with flags 0x" << std::hex << static_cast<uint32_t> (flags) << std::dec);
+  m_tcp->SendPacket (p, header, m_endPoint->GetLocalAddress (),
+                     m_endPoint->GetPeerAddress (), m_boundnetdevice);
+  m_rtt->SentSeq (seq, sz);       // notify the RTT
+  // Notify the application of the data being sent unless this is a retransmit
+  if (seq == m_nextTxSequence)
+    {
+      Simulator::ScheduleNow (&TcpSocketBase::NotifyDataSent, this, sz);
+    }
+  // Update highTxMark
+  m_highTxMark = std::max (seq + sz, m_highTxMark.Get ());
+  return sz;
+}
+
+/** Send as much pending data as possible according to the Tx window. Note that
+ *  this function did not implement the PSH flag
+ */
 bool
 TcpSocketBase::SendPendingData (bool withAck)
 {
@@ -1324,57 +1443,18 @@
         {
           break; // No more
         }
-      uint32_t s = std::min (w, m_segmentSize);  // Send no more than window
-      Ptr<Packet> p = m_txBuffer.CopyFromSequence (s, m_nextTxSequence);
-      NS_LOG_LOGIC ("TcpSocketBase " << this << " SendPendingData" <<
-                    " txseq " << m_nextTxSequence <<
-                    " s " << s << " datasize " << p->GetSize ());
-      uint8_t flags = 0;
-      uint32_t sz = p->GetSize (); // Size of packet
-      uint32_t remainingData = m_txBuffer.SizeFromSequence (m_nextTxSequence + SequenceNumber32 (sz));
-      if (m_closeOnEmpty && (remainingData == 0))
-        {
-          flags = TcpHeader::FIN;
-          if (m_state == ESTABLISHED)
-            { // On active close: I am the first one to send FIN
-              NS_LOG_INFO ("ESTABLISHED -> FIN_WAIT_1");
-              m_state = FIN_WAIT_1;
-            }
-          else
-            { // On passive close: Peer sent me FIN already
-              NS_LOG_INFO ("CLOSE_WAIT -> LAST_ACK");
-              m_state = LAST_ACK;
-            }
-        }
-      if (withAck)
+      // Nagle's algorithm (RFC896): Hold off sending if there is unacked data
+      // in the buffer and the amount of data to send is less than one segment
+      if (!m_noDelay && UnAckDataCount () > 0 &&
+          m_txBuffer.SizeFromSequence (m_nextTxSequence) < m_segmentSize)
         {
-          flags |= TcpHeader::ACK;
+          NS_LOG_LOGIC ("Invoking Nagle's algorithm. Wait to send.");
+          break;
         }
-      TcpHeader header;
-      header.SetFlags (flags);
-      header.SetSequenceNumber (m_nextTxSequence);
-      header.SetAckNumber (m_rxBuffer.NextRxSequence ());
-      header.SetSourcePort (m_endPoint->GetLocalPort ());
-      header.SetDestinationPort (m_endPoint->GetPeerPort ());
-      header.SetWindowSize (AdvertisedWindowSize ());
-      if (m_retxEvent.IsExpired () )
-        { // Schedule retransmit
-          m_rto = m_rtt->RetransmitTimeout ();
-          NS_LOG_LOGIC (this << " SendPendingData Schedule ReTxTimeout at time " <<
-                        Simulator::Now ().GetSeconds () << " to expire at time " <<
-                        (Simulator::Now () + m_rto.Get ()).GetSeconds () );
-          m_retxEvent = Simulator::Schedule (m_rto, &TcpSocketBase::ReTxTimeout, this);
-        }
-      NS_LOG_LOGIC ("Send packet via TcpL4Protocol with flags 0x" << std::hex << static_cast<uint32_t> (flags) << std::dec);
-      m_tcp->SendPacket (p, header, m_endPoint->GetLocalAddress (),
-                         m_endPoint->GetPeerAddress (), m_boundnetdevice);
-      m_rtt->SentSeq (m_nextTxSequence, sz);       // notify the RTT
-      // Notify the application of the data being sent
-      Simulator::ScheduleNow (&TcpSocketBase::NotifyDataSent, this, sz);
+      uint32_t s = std::min (w, m_segmentSize);  // Send no more than window
+      uint32_t sz = SendDataPacket (m_nextTxSequence, s, withAck);
       nPacketsSent++;                             // Count sent this loop
       m_nextTxSequence += sz;                     // Advance next tx sequence
-      // Update highTxMark
-      m_highTxMark = std::max (m_nextTxSequence, m_highTxMark);
     }
   NS_LOG_LOGIC ("SendPendingData sent " << nPacketsSent << " packets");
   return (nPacketsSent > 0);
@@ -1414,8 +1494,7 @@
 uint16_t
 TcpSocketBase::AdvertisedWindowSize ()
 {
-  uint32_t max = 0xffff;
-  return std::min (m_rxBuffer.MaxBufferSize () - m_rxBuffer.Size (), max);
+  return std::min (m_rxBuffer.MaxBufferSize () - m_rxBuffer.Size (), (uint32_t)m_maxWinSize);
 }
 
 // Receipt of new packet, put into Rx buffer
@@ -1435,8 +1514,8 @@
       return;
     }
   // Now send a new ACK packet acknowledging all received and delivered data
-  if (tcpHeader.GetSequenceNumber () > expectedSeq)
-    { // Out of sequence packet: Always ACK
+  if (m_rxBuffer.Size () > m_rxBuffer.Available () || m_rxBuffer.NextRxSequence () > expectedSeq + p->GetSize ())
+    { // A gap exists in the buffer, or we filled a gap: Always ACK
       SendEmptyPacket (TcpHeader::ACK);
     }
   else
@@ -1451,6 +1530,7 @@
         {
           m_delAckEvent = Simulator::Schedule (m_delAckTimeout,
                                                &TcpSocketBase::DelAckTimeout, this);
+          NS_LOG_LOGIC (this << " scheduled delayed ACK at " << (Simulator::Now () + Simulator::GetDelayLeft (m_delAckEvent)).GetSeconds ());
         }
     }
   // Notify app to receive if necessary
@@ -1478,7 +1558,7 @@
   // Use m_rtt for the estimation. Note, RTT of duplicated acknowledgement
   // (which should be ignored) is handled by m_rtt. Once timestamp option
   // is implemented, this function would be more elaborated.
-  m_rtt->AckSeq (tcpHeader.GetAckNumber () );
+  m_lastRtt = m_rtt->AckSeq (tcpHeader.GetAckNumber () );
 };
 
 // Called by the ReceivedAck() when new ACK received and by ProcessSynRcvd()
@@ -1543,8 +1623,8 @@
   NS_LOG_LOGIC (this << " ReTxTimeout Expired at time " << Simulator::Now ().GetSeconds ());
   // If erroneous timeout in closed/timed-wait state, just return
   if (m_state == CLOSED || m_state == TIME_WAIT) return;
-  // If all data are received, just return
-  if (m_state <= ESTABLISHED && m_txBuffer.HeadSequence () >= m_nextTxSequence) return;
+  // If all data are received (non-closing socket and nothing to send), just return
+  if (m_state <= ESTABLISHED && m_txBuffer.HeadSequence () >= m_highTxMark) return;
 
   Retransmit ();
 }
@@ -1587,6 +1667,7 @@
   tcpHeader.SetSourcePort (m_endPoint->GetLocalPort ());
   tcpHeader.SetDestinationPort (m_endPoint->GetPeerPort ());
   tcpHeader.SetWindowSize (AdvertisedWindowSize ());
+  AddOptions (tcpHeader);
 
   m_tcp->SendPacket (p, tcpHeader, m_endPoint->GetLocalAddress (),
                      m_endPoint->GetPeerAddress (), m_boundnetdevice);
@@ -1609,7 +1690,6 @@
 TcpSocketBase::DoRetransmit ()
 {
   NS_LOG_FUNCTION (this);
-  uint8_t flags = TcpHeader::ACK;
   // Retransmit SYN packet
   if (m_state == SYN_SENT)
     {
@@ -1632,35 +1712,12 @@
         }
       return;
     }
-  // Retransmit a data packet: Extract data
-  Ptr<Packet> p = m_txBuffer.CopyFromSequence (m_segmentSize, m_txBuffer.HeadSequence ());
-  // Close-on-Empty check
-  if (m_closeOnEmpty && m_txBuffer.Size () == p->GetSize ())
-    {
-      flags |= TcpHeader::FIN;
-    }
-  // Reset transmission timeout
+  // Retransmit a data packet: Call SendDataPacket
   NS_LOG_LOGIC ("TcpSocketBase " << this << " retxing seq " << m_txBuffer.HeadSequence ());
-  if (m_retxEvent.IsExpired ())
-    {
-      m_rto = m_rtt->RetransmitTimeout ();
-      NS_LOG_LOGIC (this << " Schedule ReTxTimeout at time " <<
-                    Simulator::Now ().GetSeconds () << " to expire at time " <<
-                    (Simulator::Now () + m_rto.Get ()).GetSeconds ());
-      m_retxEvent = Simulator::Schedule (m_rto, &TcpSocketBase::ReTxTimeout, this);
-    }
-  m_rtt->SentSeq (m_txBuffer.HeadSequence (), p->GetSize ());
-  // And send the packet
-  TcpHeader tcpHeader;
-  tcpHeader.SetSequenceNumber (m_txBuffer.HeadSequence ());
-  tcpHeader.SetAckNumber (m_rxBuffer.NextRxSequence ());
-  tcpHeader.SetSourcePort (m_endPoint->GetLocalPort ());
-  tcpHeader.SetDestinationPort (m_endPoint->GetPeerPort ());
-  tcpHeader.SetFlags (flags);
-  tcpHeader.SetWindowSize (AdvertisedWindowSize ());
+  uint32_t sz = SendDataPacket (m_txBuffer.HeadSequence (), m_segmentSize, true);
+  // In case of RTO, advance m_nextTxSequence
+  m_nextTxSequence = std::max (m_nextTxSequence.Get (), m_txBuffer.HeadSequence () + sz);
 
-  m_tcp->SendPacket (p, tcpHeader, m_endPoint->GetLocalAddress (),
-                     m_endPoint->GetPeerAddress (), m_boundnetdevice);
 }
 
 void
@@ -1670,6 +1727,20 @@
   m_persistEvent.Cancel ();
   m_delAckEvent.Cancel ();
   m_lastAckEvent.Cancel ();
+  m_timewaitEvent.Cancel ();
+}
+
+/** Move TCP to Time_Wait state and schedule a transition to Closed state */
+void
+TcpSocketBase::TimeWait ()
+{
+  NS_LOG_INFO (TcpStateName[m_state] << " -> TIME_WAIT");
+  m_state = TIME_WAIT;
+  CancelAllTimers ();
+  // Move from TIME_WAIT to CLOSED after 2*MSL. Max segment lifetime is 2 min
+  // according to RFC793, p.28
+  m_timewaitEvent = Simulator::Schedule (Seconds (2*m_msl),
+                                         &TcpSocketBase::CloseAndNotify, this);
 }
 
 /** Below are the attribute get/set functions */
@@ -1726,13 +1797,13 @@
 void
 TcpSocketBase::SetConnCount (uint32_t count)
 {
-  m_cnCount = count;
+  m_cnRetries = count;
 }
 
 uint32_t
 TcpSocketBase::GetConnCount (void) const
 {
-  return m_cnCount;
+  return m_cnRetries;
 }
 
 void
@@ -1760,6 +1831,18 @@
 }
 
 void
+TcpSocketBase::SetTcpNoDelay (bool noDelay)
+{
+  m_noDelay = noDelay;
+}
+
+bool
+TcpSocketBase::GetTcpNoDelay (void) const
+{
+  return m_noDelay;
+}
+
+void
 TcpSocketBase::SetPersistTimeout (Time timeout)
 {
   m_persistTimeout = timeout;
@@ -1779,9 +1862,21 @@
 }
 
 bool
-TcpSocketBase::GetAllowBroadcast () const
+TcpSocketBase::GetAllowBroadcast (void) const
 {
   return false;
 }
 
+/** Placeholder function for future extension that reads more from the TCP header */
+void
+TcpSocketBase::ReadOptions (const TcpHeader&)
+{
+}
+
+/** Placeholder function for future extension that changes the TCP header */
+void
+TcpSocketBase::AddOptions (TcpHeader&)
+{
+}
+
 } // namespace ns3
--- a/src/internet/model/tcp-socket-base.h	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/model/tcp-socket-base.h	Fri Dec 16 18:51:18 2011 +0100
@@ -1,5 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
+ * Copyright (c) 2007 Georgia Tech Research Corporation
  * Copyright (c) 2010 Adrian Sai-wah Tam
  *
  * This program is free software; you can redistribute it and/or modify
@@ -53,7 +54,7 @@
  * functions where the sliding window mechanism is handled here. This class
  * provides connection orientation and sliding window flow control. Part of
  * this class is modified from the original NS-3 TCP socket implementation
- * (TcpSocketImpl) by Raj Bhattacharjea.
+ * (TcpSocketImpl) by Raj Bhattacharjea <raj.b@gatech.edu> of Georgia Tech.
  */
 class TcpSocketBase : public TcpSocket
 {
@@ -115,10 +116,12 @@
   virtual Time     GetDelAckTimeout (void) const;
   virtual void     SetDelAckMaxCount (uint32_t count);
   virtual uint32_t GetDelAckMaxCount (void) const;
+  virtual void     SetTcpNoDelay (bool noDelay);
+  virtual bool     GetTcpNoDelay (void) const;
   virtual void     SetPersistTimeout (Time timeout);
   virtual Time     GetPersistTimeout (void) const;
   virtual bool     SetAllowBroadcast (bool allowBroadcast);
-  virtual bool     GetAllowBroadcast () const;
+  virtual bool     GetAllowBroadcast (void) const;
 
   // Helper functions: Connection set up
   int SetupCallback (void);        // Common part of the two Bind(), i.e. set callback and remembering local addr:port
@@ -128,11 +131,13 @@
   void CompleteFork (Ptr<Packet>, const TcpHeader&, const Address& fromAddress, const Address& toAdress);
 
   // Helper functions: Transfer operation
-  void ForwardUp (Ptr<Packet> packet, Ipv4Header header, uint16_t port, Ptr<Ipv4Interface> incomingInterface); //Get a pkt from L3
+  void ForwardUp (Ptr<Packet> packet, Ipv4Header header, uint16_t port, Ptr<Ipv4Interface> incomingInterface);
+  virtual void DoForwardUp (Ptr<Packet> packet, Ipv4Header header, uint16_t port, Ptr<Ipv4Interface> incomingInterface); //Get a pkt from L3
   bool SendPendingData (bool withAck = false); // Send as much as the window allows
+  uint32_t SendDataPacket (SequenceNumber32 seq, uint32_t maxSize, bool withAck); // Send a data packet
   void SendEmptyPacket (uint8_t flags); // Send a empty packet that carries a flag, e.g. ACK
   void SendRST (void); // Send reset and tear down this socket
-  bool OutOfRange (SequenceNumber32 s) const; // Check if a sequence number is within rx window
+  bool OutOfRange (SequenceNumber32 head, SequenceNumber32 tail) const; // Check if a sequence number range is within the rx window
 
   // Helper functions: Connection close
   int DoClose (void); // Close a socket by sending RST, FIN, or FIN+ACK, depend on the current state
@@ -142,6 +147,7 @@
   void PeerClose (Ptr<Packet>, const TcpHeader&); // Received a FIN from peer, notify rx buffer
   void DoPeerClose (void); // FIN is in sequence, notify app and respond with a FIN
   void CancelAllTimers (void); // Cancel all timer when endpoint is deleted
+  void TimeWait (void);  // Move from CLOSING or FIN_WAIT_2 to TIME_WAIT state
 
   // State transition functions
   void ProcessEstablished (Ptr<Packet>, const TcpHeader&); // Received a packet upon ESTABLISHED state
@@ -172,6 +178,8 @@
   virtual void LastAckTimeout (void); // Timeout at LAST_ACK, close the connection
   virtual void PersistTimeout (void); // Send 1 byte probe to get an updated window size
   virtual void DoRetransmit (void); // Retransmit the oldest packet
+  virtual void ReadOptions (const TcpHeader&); // Read option from incoming packets
+  virtual void AddOptions (TcpHeader&); // Add option to outgoing packets
 
 protected:
   // Counters and events
@@ -179,10 +187,13 @@
   EventId           m_lastAckEvent;    //< Last ACK timeout event
   EventId           m_delAckEvent;     //< Delayed ACK timeout event
   EventId           m_persistEvent;    //< Persist event: Send 1 byte to probe for a non-zero Rx window
+  EventId           m_timewaitEvent;   //< TIME_WAIT expiration event: Move this socket to CLOSED state
   uint32_t          m_dupAckCount;     //< Dupack counter
   uint32_t          m_delAckCount;     //< Delayed ACK counter
   uint32_t          m_delAckMaxCount;  //< Number of packet to fire an ACK before delay timeout
+  bool              m_noDelay;         //< Set to true to disable Nagle's algorithm
   uint32_t          m_cnCount;         //< Count of remaining connection retries
+  uint32_t          m_cnRetries;       //< Number of connection retries before giving up
   TracedValue<Time> m_rto;             //< Retransmit timeout
   TracedValue<Time> m_lastRtt;         //< Last RTT sample collected
   Time              m_delAckTimeout;   //< Time to delay an ACK
@@ -211,9 +222,11 @@
   bool                     m_shutdownSend;  //< Send no longer allowed
   bool                     m_shutdownRecv;  //< Receive no longer allowed
   bool                     m_connected;     //< Connection established
+  double                   m_msl;           //< Max segment lifetime
 
   // Window management
   uint32_t              m_segmentSize; //< Segment size
+  uint16_t              m_maxWinSize;  //< Maximum window size to advertise
   TracedValue<uint32_t> m_rWnd;        //< Flow control window at remote side
 };
 
--- a/src/internet/model/tcp-socket.cc	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/model/tcp-socket.cc	Fri Dec 16 18:51:18 2011 +0100
@@ -22,6 +22,7 @@
 #include "ns3/log.h"
 #include "ns3/uinteger.h"
 #include "ns3/double.h"
+#include "ns3/boolean.h"
 #include "ns3/trace-source-accessor.h"
 #include "ns3/nstime.h"
 #include "tcp-socket.h"
@@ -93,6 +94,11 @@
                    MakeUintegerAccessor (&TcpSocket::GetDelAckMaxCount,
                                          &TcpSocket::SetDelAckMaxCount),
                    MakeUintegerChecker<uint32_t> ())
+    .AddAttribute ("TcpNoDelay", "Set to true to disable Nagle's algorithm",
+                   BooleanValue (true),
+                   MakeBooleanAccessor (&TcpSocket::GetTcpNoDelay,
+                                        &TcpSocket::SetTcpNoDelay),
+                   MakeBooleanChecker ())
     .AddAttribute ("PersistTimeout",
                    "Persist timeout to probe for rx window",
                    TimeValue (Seconds (6)),
--- a/src/internet/model/tcp-socket.h	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/model/tcp-socket.h	Fri Dec 16 18:51:18 2011 +0100
@@ -90,6 +90,8 @@
   virtual Time GetDelAckTimeout (void) const = 0;
   virtual void SetDelAckMaxCount (uint32_t count) = 0;
   virtual uint32_t GetDelAckMaxCount (void) const = 0;
+  virtual void SetTcpNoDelay (bool noDelay) = 0;
+  virtual bool GetTcpNoDelay (void) const = 0;
   virtual void SetPersistTimeout (Time timeout) = 0;
   virtual Time GetPersistTimeout (void) const = 0;
 
--- a/src/internet/model/tcp-tahoe.cc	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/model/tcp-tahoe.cc	Fri Dec 16 18:51:18 2011 +0100
@@ -40,6 +40,10 @@
   static TypeId tid = TypeId ("ns3::TcpTahoe")
     .SetParent<TcpSocketBase> ()
     .AddConstructor<TcpTahoe> ()
+    .AddAttribute ("ReTxThreshold", "Threshold for fast retransmit",
+                    UintegerValue (3),
+                    MakeUintegerAccessor (&TcpTahoe::m_retxThresh),
+                    MakeUintegerChecker<uint32_t> ())
     .AddTraceSource ("CongestionWindow",
                      "The TCP connection's congestion window",
                      MakeTraceSourceAccessor (&TcpTahoe::m_cWnd))
@@ -47,7 +51,7 @@
   return tid;
 }
 
-TcpTahoe::TcpTahoe (void) : m_initialCWnd (0)
+TcpTahoe::TcpTahoe (void) : m_initialCWnd (1), m_retxThresh (3)
 {
   NS_LOG_FUNCTION (this);
 }
@@ -56,7 +60,8 @@
   : TcpSocketBase (sock),
     m_cWnd (sock.m_cWnd),
     m_ssThresh (sock.m_ssThresh),
-    m_initialCWnd (sock.m_initialCWnd)
+    m_initialCWnd (sock.m_initialCWnd),
+    m_retxThresh (sock.m_retxThresh)
 {
   NS_LOG_FUNCTION (this);
   NS_LOG_LOGIC ("Invoked the copy constructor");
@@ -127,7 +132,7 @@
 TcpTahoe::DupAck (const TcpHeader& t, uint32_t count)
 {
   NS_LOG_FUNCTION (this << "t " << count);
-  if (count == 3)
+  if (count == m_retxThresh)
     { // triple duplicate ack triggers fast retransmit (RFC2001, sec.3)
       NS_LOG_INFO ("Triple Dup Ack: old ssthresh " << m_ssThresh << " cwnd " << m_cWnd);
       // fast retransmit in Tahoe means triggering RTO earlier. Tx is restarted
@@ -149,8 +154,8 @@
   NS_LOG_LOGIC (this << " ReTxTimeout Expired at time " << Simulator::Now ().GetSeconds ());
   // If erroneous timeout in closed/timed-wait state, just return
   if (m_state == CLOSED || m_state == TIME_WAIT) return;
-  // If all data are received, just return
-  if (m_txBuffer.HeadSequence () >= m_nextTxSequence) return;
+  // If all data are received (non-closing socket and nothing to send), just return
+  if (m_state <= ESTABLISHED && m_txBuffer.HeadSequence () >= m_highTxMark) return;
 
   m_ssThresh = std::max (static_cast<unsigned> (m_cWnd / 2), m_segmentSize * 2);  // Half ssthresh
   m_cWnd = m_segmentSize;                   // Set cwnd to 1 segSize (RFC2001, sec.2)
--- a/src/internet/model/tcp-tahoe.h	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/model/tcp-tahoe.h	Fri Dec 16 18:51:18 2011 +0100
@@ -74,6 +74,7 @@
   TracedValue<uint32_t>  m_cWnd;         //< Congestion window
   uint32_t               m_ssThresh;     //< Slow Start Threshold
   uint32_t               m_initialCWnd;  //< Initial cWnd value
+  uint32_t               m_retxThresh;   //< Fast Retransmit threshold
 };
 
 } // namespace ns3
--- a/src/internet/model/udp-socket-impl.cc	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/model/udp-socket-impl.cc	Fri Dec 16 18:51:18 2011 +0100
@@ -84,7 +84,7 @@
        * when DeAllocate is called, it will call into
        * Ipv4EndPointDemux::Deallocate which triggers
        * a delete of the associated endPoint which triggers
-       * in turn a call to the method ::Destroy below
+       * in turn a call to the method UdpSocketImpl::Destroy below
        * will will zero the m_endPoint field.
        */
       NS_ASSERT (m_endPoint != 0);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet/test/ipv6-address-generator-test-suite.cc	Fri Dec 16 18:51:18 2011 +0100
@@ -0,0 +1,291 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 University of Washington
+ * Copyright (c) 2011 Atishay Jain
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "ns3/test.h"
+#include "ns3/ipv6-address-generator.h"
+#include "ns3/simulation-singleton.h"
+
+namespace ns3 {
+
+class NetworkNumber6AllocatorTestCase : public TestCase
+{
+public:
+  NetworkNumber6AllocatorTestCase ();
+  virtual void DoRun (void);
+  virtual void DoTeardown (void);
+};
+
+NetworkNumber6AllocatorTestCase::NetworkNumber6AllocatorTestCase ()
+  : TestCase ("Make sure the network number allocator is working on some of network prefixes.")
+{
+}
+void
+NetworkNumber6AllocatorTestCase::DoTeardown (void)
+{
+  Ipv6AddressGenerator::Reset ();
+}
+void
+NetworkNumber6AllocatorTestCase::DoRun (void)
+{
+  Ipv6Address network;
+
+  Ipv6AddressGenerator::Init (Ipv6Address ("1::0:0:0"), Ipv6Prefix ("FFFF::0"),
+                              Ipv6Address ("::"));
+  network = Ipv6AddressGenerator::GetNetwork (Ipv6Prefix ("FFFF::0"));
+  NS_TEST_EXPECT_MSG_EQ (network, Ipv6Address ("1::0:0:0"), "network should equal the initialized network for given prefix");
+  network = Ipv6AddressGenerator::NextNetwork (Ipv6Prefix ("FFFF::0"));
+  NS_TEST_EXPECT_MSG_EQ (network, Ipv6Address ("2::0:0:0"), "network should equal next network");
+
+  Ipv6AddressGenerator::Init (Ipv6Address ("0:1::0:0"),
+                              Ipv6Prefix ("FFFF:FFFF::0"), Ipv6Address ("::"));
+  network = Ipv6AddressGenerator::GetNetwork (Ipv6Prefix ("FFFF:FFFF::0"));
+  NS_TEST_EXPECT_MSG_EQ (network, Ipv6Address ("0:1::0"), "network should equal the initialized network for given prefix");
+  network = Ipv6AddressGenerator::NextNetwork (Ipv6Prefix ("FFFF:FFFF::0"));
+  NS_TEST_EXPECT_MSG_EQ (network, Ipv6Address ("0:2::0"), "network should equal next network");
+
+  Ipv6AddressGenerator::Init (Ipv6Address ("0:0:1::0"),
+                              Ipv6Prefix ("FFFF:FFFF:FFFF::0"), Ipv6Address ("::0"));
+  network = Ipv6AddressGenerator::GetNetwork (Ipv6Prefix ("FFFF:FFFF:FFFF::0"));
+  NS_TEST_EXPECT_MSG_EQ (network, Ipv6Address ("0:0:1::0"), "network should equal the initialized network for given prefix");
+  network = Ipv6AddressGenerator::NextNetwork (Ipv6Prefix ("FFFF:FFFF:FFFF::0"));
+  NS_TEST_EXPECT_MSG_EQ (network, Ipv6Address ("0:0:2::0"), "network should equal next network");
+
+}
+
+class AddressAllocator6TestCase : public TestCase
+{
+public:
+  AddressAllocator6TestCase ();
+private:
+  virtual void DoRun (void);
+  virtual void DoTeardown (void);
+};
+
+AddressAllocator6TestCase::AddressAllocator6TestCase ()
+  : TestCase ("Sanity check on allocation of addresses")
+{
+}
+
+void
+AddressAllocator6TestCase::DoRun (void)
+{
+  Ipv6Address address;
+
+  Ipv6AddressGenerator::Init (Ipv6Address ("2001::0"), Ipv6Prefix (64));
+  address = Ipv6AddressGenerator::GetNetwork (Ipv6Prefix (64));
+  NS_TEST_EXPECT_MSG_EQ (address, Ipv6Address ("2001::0"), "address should equal the initialized address for given prefix");
+  Ipv6AddressGenerator::NextNetwork (Ipv6Prefix (64));
+  address = Ipv6AddressGenerator::GetNetwork (Ipv6Prefix (64));
+  NS_TEST_EXPECT_MSG_EQ (address, Ipv6Address ("2001:0:0:1::0"), "address should equal the initialized address for given prefix");
+  address = Ipv6AddressGenerator::GetAddress (Ipv6Prefix (64));
+  NS_TEST_EXPECT_MSG_EQ (address, Ipv6Address ("2001:0:0:1::1"), "address should equal the initialized address for given prefix");
+  address = Ipv6AddressGenerator::NextAddress (Ipv6Prefix (64));
+  NS_TEST_EXPECT_MSG_EQ (address, Ipv6Address ("2001:0:0:1::1"), "address should equal the initialized address for given prefix");
+  address = Ipv6AddressGenerator::NextAddress (Ipv6Prefix (64));
+  NS_TEST_EXPECT_MSG_EQ (address, Ipv6Address ("2001:0:0:1::2"), "address should equal the initialized address for given prefix");
+
+  Ipv6AddressGenerator::Init (Ipv6Address ("1::"), Ipv6Prefix ("FFFF::"),
+                              Ipv6Address ("::3"));
+  address = Ipv6AddressGenerator::NextAddress (Ipv6Prefix (16));
+  NS_TEST_EXPECT_MSG_EQ (address, Ipv6Address ("1::3"), "address should equal initialized address for given prefix");
+  address = Ipv6AddressGenerator::NextAddress (Ipv6Prefix (16));
+  NS_TEST_EXPECT_MSG_EQ (address, Ipv6Address ("1::4"), "address should equal next address");
+
+}
+
+void
+AddressAllocator6TestCase::DoTeardown (void)
+{
+  Ipv6AddressGenerator::Reset ();
+  Simulator::Destroy ();
+}
+
+
+class NetworkAndAddress6TestCase : public TestCase
+{
+public:
+  NetworkAndAddress6TestCase ();
+  virtual void DoRun (void);
+  virtual void DoTeardown (void);
+};
+
+NetworkAndAddress6TestCase::NetworkAndAddress6TestCase ()
+  : TestCase ("Make sure Network and address allocation play together.")
+{
+}
+
+void
+NetworkAndAddress6TestCase::DoTeardown (void)
+{
+  Ipv6AddressGenerator::Reset ();
+  Simulator::Destroy ();
+}
+
+void
+NetworkAndAddress6TestCase::DoRun (void)
+{
+  Ipv6Address address;
+  Ipv6Address network;
+
+  Ipv6AddressGenerator::Init (Ipv6Address ("3::"), Ipv6Prefix ("FFFF::"),
+                              Ipv6Address ("::3"));
+  address = Ipv6AddressGenerator::NextAddress (Ipv6Prefix (16));
+  NS_TEST_EXPECT_MSG_EQ (address, Ipv6Address ("3::3"), "address should equal initialized address for given prefix");
+  address = Ipv6AddressGenerator::NextAddress (Ipv6Prefix (16));
+  NS_TEST_EXPECT_MSG_EQ (address, Ipv6Address ("3::4"), "address should equal next address for given prefix");
+
+  network = Ipv6AddressGenerator::NextNetwork (Ipv6Prefix ("FFFF::"));
+  NS_TEST_EXPECT_MSG_EQ (network, Ipv6Address ("4::0"), "address should equal next address for given prefix");
+  address = Ipv6AddressGenerator::NextAddress (Ipv6Prefix (16));
+  NS_TEST_EXPECT_MSG_EQ (address, Ipv6Address ("4::3"), "address should equal next address for given prefix");
+
+}
+
+class ExampleAddress6GeneratorTestCase : public TestCase
+{
+public:
+  ExampleAddress6GeneratorTestCase ();
+private:
+  virtual void DoRun (void);
+  virtual void DoTeardown (void);
+};
+
+ExampleAddress6GeneratorTestCase::ExampleAddress6GeneratorTestCase ()
+  : TestCase ("A typical real-world example")
+{
+}
+
+void
+ExampleAddress6GeneratorTestCase::DoTeardown (void)
+{
+  Ipv6AddressGenerator::Reset ();
+}
+
+void
+ExampleAddress6GeneratorTestCase::DoRun (void)
+{
+  Ipv6Address address;
+
+  Ipv6AddressGenerator::Init (Ipv6Address ("2001:0AB8::"),
+                              Ipv6Prefix ("FFFF:FFFF:FFFF::0"), Ipv6Address ("::3"));
+  address = Ipv6AddressGenerator::NextAddress (Ipv6Prefix (48));
+  NS_TEST_EXPECT_MSG_EQ (address, Ipv6Address ("2001:0AB8::0:3"), "address should equal initialized address for given prefix");
+  address = Ipv6AddressGenerator::NextAddress (Ipv6Prefix (48));
+  NS_TEST_EXPECT_MSG_EQ (address, Ipv6Address ("2001:0AB8::0:4"), "address should equal next address for given prefix");
+  address = Ipv6AddressGenerator::NextAddress (Ipv6Prefix (48));
+  NS_TEST_EXPECT_MSG_EQ (address, Ipv6Address ("2001:0AB8::0:5"), "address should equal next address for given prefix");
+  //
+  // Allocate the next network based on the prefix passed in, which should
+  // be 2001:0AB0:0001
+  //
+  Ipv6AddressGenerator::NextNetwork (Ipv6Prefix ("FFFF:FFFF:FFFF::0"));
+  //
+  // reset first address to be allocated back to ::0:3
+  //
+  Ipv6AddressGenerator::InitAddress (Ipv6Address ("::3"),
+                                     Ipv6Prefix (48));
+  //
+  // The first address we should get is the network and address ORed
+  //
+  address = Ipv6AddressGenerator::NextAddress (Ipv6Prefix (48));
+  NS_TEST_EXPECT_MSG_EQ (address, Ipv6Address ("2001:0AB8:1::3"), "address should equal initialized address for given prefix");
+}
+
+class AddressCollision6TestCase : public TestCase
+{
+public:
+  AddressCollision6TestCase ();
+private:
+  void DoRun (void);
+  void DoTeardown (void);
+};
+
+AddressCollision6TestCase::AddressCollision6TestCase ()
+  : TestCase ("Make sure that the address collision logic works.")
+{
+}
+
+void
+AddressCollision6TestCase::DoTeardown (void)
+{
+  Ipv6AddressGenerator::Reset ();
+  Simulator::Destroy ();
+}
+void
+AddressCollision6TestCase::DoRun (void)
+{
+  Ipv6AddressGenerator::AddAllocated ("0::0:5");
+  Ipv6AddressGenerator::AddAllocated ("0::0:10");
+  Ipv6AddressGenerator::AddAllocated ("0::0:15");
+  Ipv6AddressGenerator::AddAllocated ("0::0:20");
+
+  Ipv6AddressGenerator::AddAllocated ("0::0:4");
+  Ipv6AddressGenerator::AddAllocated ("0::0:3");
+  Ipv6AddressGenerator::AddAllocated ("0::0:2");
+  Ipv6AddressGenerator::AddAllocated ("0::0:1");
+
+  Ipv6AddressGenerator::AddAllocated ("0::0:6");
+  Ipv6AddressGenerator::AddAllocated ("0::0:7");
+  Ipv6AddressGenerator::AddAllocated ("0::0:8");
+  Ipv6AddressGenerator::AddAllocated ("0::0:9");
+
+  Ipv6AddressGenerator::AddAllocated ("0::0:11");
+  Ipv6AddressGenerator::AddAllocated ("0::0:12");
+  Ipv6AddressGenerator::AddAllocated ("0::0:13");
+  Ipv6AddressGenerator::AddAllocated ("0::0:14");
+
+  Ipv6AddressGenerator::AddAllocated ("0::0:19");
+  Ipv6AddressGenerator::AddAllocated ("0::0:18");
+  Ipv6AddressGenerator::AddAllocated ("0::0:17");
+  Ipv6AddressGenerator::AddAllocated ("0::0:16");
+
+  Ipv6AddressGenerator::TestMode ();
+  bool added = Ipv6AddressGenerator::AddAllocated ("0::0:21");
+  NS_TEST_EXPECT_MSG_EQ (added, true, "address should get allocated");
+
+  added = Ipv6AddressGenerator::AddAllocated ("0::0:4");
+  NS_TEST_EXPECT_MSG_EQ (added, false, "address should not get allocated");
+
+  added = Ipv6AddressGenerator::AddAllocated ("0::0:9");
+  NS_TEST_EXPECT_MSG_EQ (added, false, "address should not get allocated");
+
+  added = Ipv6AddressGenerator::AddAllocated ("0::0:16");
+  NS_TEST_EXPECT_MSG_EQ (added, false, "address should not get allocated");
+
+  added = Ipv6AddressGenerator::AddAllocated ("0::0:21");
+  NS_TEST_EXPECT_MSG_EQ (added, false, "address should not get allocated");
+}
+
+
+static class Ipv6AddressGeneratorTestSuite : public TestSuite
+{
+public:
+  Ipv6AddressGeneratorTestSuite ()
+    : TestSuite ("ipv6-address-generator")
+  {
+    AddTestCase (new NetworkNumber6AllocatorTestCase ());
+    AddTestCase (new AddressAllocator6TestCase ());
+    AddTestCase (new NetworkAndAddress6TestCase ());
+    AddTestCase (new ExampleAddress6GeneratorTestCase ());
+    AddTestCase (new AddressCollision6TestCase ());
+  }
+} g_ipv6AddressGeneratorTestSuite;
+
+} // namespace ns3
+
--- a/src/internet/wscript	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/wscript	Fri Dec 16 18:51:18 2011 +0100
@@ -183,6 +183,7 @@
         'helper/ipv6-address-helper.cc',
         'helper/ipv6-interface-container.cc',
         'helper/ipv6-routing-helper.cc',
+        'model/ipv6-address-generator.cc',
         ]
 
     internet_test = bld.create_ns3_module_test_library('internet')
@@ -204,6 +205,7 @@
         'test/ipv6-test.cc',
         'test/tcp-test.cc',
         'test/udp-test.cc',
+        'test/ipv6-address-generator-test-suite.cc',
         ]
 
     headers = bld.new_task_gen(features=['ns3header'])
@@ -276,6 +278,7 @@
         'helper/ipv6-address-helper.h',
         'helper/ipv6-interface-container.h',
         'helper/ipv6-routing-helper.h',
+        'model/ipv6-address-generator.h',
        ]
 
     if bld.env['NSC_ENABLED']:
--- a/src/lte/bindings/modulegen__gcc_ILP32.py	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/lte/bindings/modulegen__gcc_ILP32.py	Fri Dec 16 18:51:18 2011 +0100
@@ -3989,6 +3989,10 @@
     cls.add_constructor([param('ns3::SpectrumInterference const &', 'arg0')])
     ## spectrum-interference.h (module 'spectrum'): ns3::SpectrumInterference::SpectrumInterference() [constructor]
     cls.add_constructor([])
+    ## spectrum-interference.h (module 'spectrum'): void ns3::SpectrumInterference::AbortRx() [member function]
+    cls.add_method('AbortRx', 
+                   'void', 
+                   [])
     ## spectrum-interference.h (module 'spectrum'): void ns3::SpectrumInterference::AddSignal(ns3::Ptr<ns3::SpectrumValue const> spd, ns3::Time const duration) [member function]
     cls.add_method('AddSignal', 
                    'void', 
@@ -5661,6 +5665,11 @@
                    'ns3::Vector', 
                    [], 
                    is_const=True)
+    ## mobility-model.h (module 'mobility'): double ns3::MobilityModel::GetRelativeSpeed(ns3::Ptr<const ns3::MobilityModel> other) const [member function]
+    cls.add_method('GetRelativeSpeed', 
+                   'double', 
+                   [param('ns3::Ptr< ns3::MobilityModel const >', 'other')], 
+                   is_const=True)
     ## mobility-model.h (module 'mobility'): static ns3::TypeId ns3::MobilityModel::GetTypeId() [member function]
     cls.add_method('GetTypeId', 
                    'ns3::TypeId', 
--- a/src/lte/bindings/modulegen__gcc_LP64.py	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/lte/bindings/modulegen__gcc_LP64.py	Fri Dec 16 18:51:18 2011 +0100
@@ -3989,6 +3989,10 @@
     cls.add_constructor([param('ns3::SpectrumInterference const &', 'arg0')])
     ## spectrum-interference.h (module 'spectrum'): ns3::SpectrumInterference::SpectrumInterference() [constructor]
     cls.add_constructor([])
+    ## spectrum-interference.h (module 'spectrum'): void ns3::SpectrumInterference::AbortRx() [member function]
+    cls.add_method('AbortRx', 
+                   'void', 
+                   [])
     ## spectrum-interference.h (module 'spectrum'): void ns3::SpectrumInterference::AddSignal(ns3::Ptr<ns3::SpectrumValue const> spd, ns3::Time const duration) [member function]
     cls.add_method('AddSignal', 
                    'void', 
@@ -5661,6 +5665,11 @@
                    'ns3::Vector', 
                    [], 
                    is_const=True)
+    ## mobility-model.h (module 'mobility'): double ns3::MobilityModel::GetRelativeSpeed(ns3::Ptr<const ns3::MobilityModel> other) const [member function]
+    cls.add_method('GetRelativeSpeed', 
+                   'double', 
+                   [param('ns3::Ptr< ns3::MobilityModel const >', 'other')], 
+                   is_const=True)
     ## mobility-model.h (module 'mobility'): static ns3::TypeId ns3::MobilityModel::GetTypeId() [member function]
     cls.add_method('GetTypeId', 
                    'ns3::TypeId', 
--- a/src/mesh/helper/mesh-stack-installer.h	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/mesh/helper/mesh-stack-installer.h	Fri Dec 16 18:51:18 2011 +0100
@@ -28,7 +28,8 @@
  *
  * \brief Prototype for class, which helps to install MAC-layer
  * routing stack to ns3::MeshPointDevice
- * \details You need to create a  MeshPointDevice and attach all
+ *
+ * You need to create a MeshPointDevice and attach all
  * interfaces to it, than call Install method
  */
 class MeshStack : public Object
--- a/src/mesh/model/dot11s/airtime-metric.h	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/mesh/model/dot11s/airtime-metric.h	Fri Dec 16 18:51:18 2011 +0100
@@ -26,16 +26,15 @@
 /**
  * \ingroup dot11s
  *
- * \brief airtime link metric calculator
+ * \brief Airtime link metric calculator
  *
- * \details Airtime link metric is defined in 11B.10 of 802.11s Draft D3.0 as:
+ * Airtime link metric is defined in 11B.10 of 802.11s Draft D3.0 as:
  *
- * airtime = (O + Bt/r)* (1 + average retry counter), where
- *
- * o  -- the PHY dependent channel access which includes frame headers, training sequences,
+ * airtime = (O + Bt/r)* (1 + average retry counter), where:
+ * - o  -- the PHY dependent channel access which includes frame headers, training sequences,
  *       access protocol frames, etc.
- * bt -- the test packet length in bits (8192 by default),
- * r  -- the current bitrate of the packet,
+ * - bt -- the test packet length in bits (8192 by default),
+ * - r  -- the current bitrate of the packet,
  *
  * Final result is expressed in units of 0.01 Time Unit = 10.24 us (as required by 802.11s draft)
  */
--- a/src/mesh/model/dot11s/hwmp-protocol.cc	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/mesh/model/dot11s/hwmp-protocol.cc	Fri Dec 16 18:51:18 2011 +0100
@@ -565,18 +565,19 @@
   std::map<Mac48Address, std::pair<uint32_t, uint32_t> >::const_iterator i = m_hwmpSeqnoMetricDatabase.find (
       prep.GetOriginatorAddress ());
   bool freshInfo (true);
+  uint32_t sequence = prep.GetDestinationSeqNumber ();
   if (i != m_hwmpSeqnoMetricDatabase.end ())
     {
-      if ((int32_t)(i->second.first - prep.GetOriginatorSeqNumber ()) > 0)
+      if ((int32_t)(i->second.first - sequence) > 0)
         {
           return;
         }
-      if (i->second.first == prep.GetOriginatorSeqNumber ())
+      if (i->second.first == sequence)
         {
           freshInfo = false;
         }
     }
-  m_hwmpSeqnoMetricDatabase[prep.GetOriginatorAddress ()] = std::make_pair (prep.GetOriginatorSeqNumber (), prep.GetMetric ());
+  m_hwmpSeqnoMetricDatabase[prep.GetOriginatorAddress ()] = std::make_pair (sequence, prep.GetMetric ());
   //update routing info
   //Now add a path to destination and add precursor to source
   NS_LOG_DEBUG ("I am " << GetAddress () << ", received prep from " << prep.GetOriginatorAddress () << ", receiver was:" << from);
@@ -597,7 +598,7 @@
         interface,
         prep.GetMetric (),
         MicroSeconds (prep.GetLifetime () * 1024),
-        prep.GetOriginatorSeqNumber ());
+        sequence);
       m_rtable->AddPrecursor (prep.GetDestinationAddress (), interface, from,
                               MicroSeconds (prep.GetLifetime () * 1024));
       if (result.retransmitter != Mac48Address::GetBroadcast ())
@@ -618,7 +619,7 @@
         interface,
         metric,
         MicroSeconds (prep.GetLifetime () * 1024),
-        prep.GetOriginatorSeqNumber ());
+        sequence);
       ReactivePathResolved (fromMp);
     }
   if (prep.GetDestinationAddress () == GetAddress ())
--- a/src/mesh/model/dot11s/hwmp-tag.h	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/mesh/model/dot11s/hwmp-tag.h	Fri Dec 16 18:51:18 2011 +0100
@@ -34,7 +34,7 @@
  * \brief Hwmp tag implements interaction between HWMP
  * protocol and MeshWifiMac
  *
- * \details Hwmp tag keeps the following:
+ * Hwmp tag keeps the following:
  * 1. When packet is passed from Hwmp to 11sMAC:
  *  - retransmitter address,
  *  - TTL value,
--- a/src/mesh/model/dot11s/peer-link-frame.h	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/mesh/model/dot11s/peer-link-frame.h	Fri Dec 16 18:51:18 2011 +0100
@@ -34,9 +34,9 @@
 /**
  * \ingroup dot11s
  *
- * \brief 802.11s Peer link management frame:
- * \details included the following (see chapters 7.4.12.1-7.4.12.3 of
- * 802.11s):
+ * \brief 802.11s Peer link management frame
+ * 
+ * Peer link management frame included the following (see chapters 7.4.12.1-7.4.12.3 of 802.11s):
  * - Subtype field
  * - Association ID field
  * - Supported rates
--- a/src/mesh/model/dot11s/peer-link.h	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/mesh/model/dot11s/peer-link.h	Fri Dec 16 18:51:18 2011 +0100
@@ -202,14 +202,14 @@
   PeerLink& operator= (const PeerLink &);
   PeerLink (const PeerLink &);
 
-  ///The number of interface I am associated with
+  /// The number of interface I am associated with
   uint32_t m_interface;
   /// pointer to MAC plugin, which is responsible for peer management
   Ptr<PeerManagementProtocolMac> m_macPlugin;
   /// Peer address
   Mac48Address m_peerAddress;
   /// Mesh point address, equal to peer address in case of single
-  //interface mesh point
+  /// interface mesh point
   Mac48Address m_peerMeshPointAddress;
   /// My ID of this link
   uint16_t m_localLinkId;
@@ -253,7 +253,7 @@
   EventId  m_beaconLossTimer;
   uint16_t m_maxBeaconLoss;
   uint16_t m_maxPacketFail;
-  //\}
+  // \}
   /// How to report my status change
   SignalStatusCallback m_linkStatusCallback;
 };
--- a/src/mesh/model/dot11s/peer-management-protocol-mac.h	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/mesh/model/dot11s/peer-management-protocol-mac.h	Fri Dec 16 18:51:18 2011 +0100
@@ -45,26 +45,30 @@
   PeerManagementProtocolMac (uint32_t interface, Ptr<PeerManagementProtocol> protocol);
   ~PeerManagementProtocolMac ();
   ///\name Inherited from plugin abstract class
-  ///\{
+  // \{
   void SetParent (Ptr<MeshWifiInterfaceMac> parent);
   bool Receive (Ptr<Packet> packet, const WifiMacHeader & header);
   bool UpdateOutcomingFrame (Ptr<Packet> packet, WifiMacHeader & header, Mac48Address from, Mac48Address to);
   void UpdateBeacon (MeshWifiBeacon & beacon) const;
-  ///\}
-  ///\name Statistics:
-  ///\{
+  // \}
+  ///\name Statistics
+  // \{
   void Report (std::ostream &) const;
   void ResetStats ();
   uint32_t GetLinkMetric (Mac48Address peerAddress);
-  ///\}
+  // \}
 private:
   PeerManagementProtocolMac& operator= (const PeerManagementProtocolMac &);
   PeerManagementProtocolMac (const PeerManagementProtocolMac &);
 
   friend class PeerManagementProtocol;
   friend class PeerLink;
-  ///\name Create peer link management frames:
-  ///\{
+  ///\name Create peer link management frames
+  // \{
+  /**
+   * \brief This structure keeps all fields in peer link management frame,
+   * which are not subclasses of WifiInformationElement
+   */
   struct PlinkFrameStart
   {
     uint8_t subtype;
@@ -75,18 +79,13 @@
   Ptr<Packet> CreatePeerLinkOpenFrame ();
   Ptr<Packet> CreatePeerLinkConfirmFrame ();
   Ptr<Packet> CreatePeerLinkCloseFrame ();
-  /**
-   * \brief This structure keeps all fields in peer link management frame,
-   * which are not subclasses of WifiInformationElement
-   */
-  /// \name Parses the start of the frame, where there are no
-  /// WifiInformationElements exist
+  /// Parses the start of the frame, where no WifiInformationElements exist
   PlinkFrameStart ParsePlinkFrame (Ptr<const Packet> packet);
-  ///\}
-  ///// Closes link when a proper number of successive transmissions have failed
+  // \}
+  ///  Closes link when a proper number of successive transmissions have failed
   void TxError (WifiMacHeader const &hdr);
   void TxOk (WifiMacHeader const &hdr);
-  ///BCA functionallity:
+  /// BCA functionality
   void SetBeaconShift (Time shift);
   void SetPeerManagerProtcol (Ptr<PeerManagementProtocol> protocol);
   void SendPeerLinkManagementFrame (
@@ -96,9 +95,10 @@
     IePeerManagement peerElement,
     IeConfiguration meshConfig
     );
-  ///\brief DUBUG only - to print established links
+  ///\brief debug only, used to print established links
   Mac48Address GetAddress () const;
   ///\name Statistics
+  // \{
   struct Statistics
   {
     uint16_t txOpen;
@@ -122,11 +122,11 @@
   struct Statistics m_stats;
   ///\}
   ///\name Information about MAC and protocol:
-  ///\{
+  // \{
   Ptr<MeshWifiInterfaceMac> m_parent;
   uint32_t m_ifIndex;
   Ptr<PeerManagementProtocol> m_protocol;
-  ///\}
+  // \}
 };
 
 } // namespace dot11s
--- a/src/mesh/model/dot11s/peer-management-protocol.cc	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/mesh/model/dot11s/peer-management-protocol.cc	Fri Dec 16 18:51:18 2011 +0100
@@ -164,7 +164,6 @@
 {
   //PM STATE Machine
   //Check that a given beacon is not from our interface
-  Simulator::Schedule (beaconInterval - TuToTime (m_maxBeaconShift + 1), &PeerManagementProtocol::DoShiftBeacon, this, interface);
   for (PeerManagementProtocolMacMap::const_iterator i = m_plugins.begin (); i != m_plugins.end (); i++)
     {
       if (i->second->GetAddress () == peerAddress)
@@ -180,6 +179,10 @@
           peerLink = InitiateLink (interface, peerAddress, Mac48Address::GetBroadcast ());
           peerLink->MLMEActivePeerLinkOpen ();
         }
+      else
+        {
+          return;
+        }
     }
   peerLink->SetBeaconInformation (Simulator::Now (), beaconInterval);
   if (GetBeaconCollisionAvoidance ())
@@ -371,81 +374,93 @@
 }
 
 void
-PeerManagementProtocol::DoShiftBeacon (uint32_t interface)
+PeerManagementProtocol::CheckBeaconCollisions (uint32_t interface)
 {
   if (!GetBeaconCollisionAvoidance ())
     {
       return;
     }
-  // If beacon interval is equal to the neighbor's one and one o more beacons received
-  // by my neighbor coincide with my beacon - apply random uniformly distributed shift from
-  // [-m_maxBeaconShift, m_maxBeaconShift] except 0.
-  UniformVariable beaconShift (-m_maxBeaconShift, m_maxBeaconShift);
   PeerLinksMap::iterator iface = m_peerLinks.find (interface);
   NS_ASSERT (iface != m_peerLinks.end ());
-  PeerManagementProtocolMacMap::const_iterator plugin = m_plugins.find (interface);
-  NS_ASSERT (plugin != m_plugins.end ());
-  // cast plugin to void, to suppress 'plugin' set but not used, compiler warning
-  // in optimized builds
-  (void) plugin;
+  NS_ASSERT (m_plugins.find (interface) != m_plugins.end ());
+
   std::map<uint32_t, Time>::const_iterator lastBeacon = m_lastBeacon.find (interface);
   std::map<uint32_t, Time>::const_iterator beaconInterval = m_beaconInterval.find (interface);
   if ((lastBeacon == m_lastBeacon.end ()) || (beaconInterval == m_beaconInterval.end ()))
     {
       return;
     }
-  if (TuToTime (m_maxBeaconShift) > m_beaconInterval[interface])
+  //my last beacon in 256 us units
+  uint16_t lastBeaconInTimeElement = (uint16_t) ((lastBeacon->second.GetMicroSeconds () >> 8) & 0xffff);
+
+  NS_ASSERT_MSG (TuToTime (m_maxBeaconShift) <= m_beaconInterval[interface], "Wrong beacon shift parameters");
+
+  if (iface->second.size () == 0)
     {
-      NS_FATAL_ERROR ("Wrong beacon shift parameters");
+      //I have no peers - may be our beacons are in collision
+      ShiftOwnBeacon (interface);
       return;
     }
+  //check whether all my peers receive my beacon and I'am not in collision with other beacons
+
   for (PeerLinksOnInterface::iterator i = iface->second.begin (); i != iface->second.end (); i++)
     {
-      IeBeaconTiming::NeighboursTimingUnitsList neighbours;
-      neighbours = (*i)->GetBeaconTimingElement ().GetNeighboursTimingElementsList ();
-      //Going through all my timing elements and detecting future beacon collisions
-      for (IeBeaconTiming::NeighboursTimingUnitsList::const_iterator j = neighbours.begin (); j
-           != neighbours.end (); j++)
+      bool myBeaconExists = false;
+      IeBeaconTiming::NeighboursTimingUnitsList neighbors = (*i)->GetBeaconTimingElement ().GetNeighboursTimingElementsList ();
+      for (IeBeaconTiming::NeighboursTimingUnitsList::const_iterator j = neighbors.begin (); j != neighbors.end (); j++)
         {
           if ((*i)->GetPeerAid () == (*j)->GetAid ())
             {
-              // I am present at neighbour's list of neighbors
-              continue;
-            }
-          //Beacon interval is stored in TU's
-          if (((*j)->GetBeaconInterval ()) != TimeToTu (beaconInterval->second))
-            {
+              // I am presented at neighbour's list of neighbors
+              myBeaconExists = true;
               continue;
             }
-          //Timing element keeps beacon receiving times in 256us units, TU=1024us
-          if ((int)((int)(*j)->GetLastBeacon () / 4 - (int)TimeToTu (lastBeacon->second)) % TimeToTu (
-                beaconInterval->second)
-              != 0)
+          if (
+            ((int16_t) ((*j)->GetLastBeacon () - lastBeaconInTimeElement) >= 0) &&
+            (((*j)->GetLastBeacon () - lastBeaconInTimeElement) % (4 * TimeToTu (beaconInterval->second)) == 0)
+            )
             {
-              continue;
+              ShiftOwnBeacon (interface);
+              return;
             }
-          int shift = 0;
-          do
-            {
-              shift = (int) beaconShift.GetValue ();
-            }
-          while (shift == 0);
-          PeerManagementProtocolMacMap::iterator plugin = m_plugins.find (interface);
-          NS_ASSERT (plugin != m_plugins.end ());
-          plugin->second->SetBeaconShift (TuToTime (shift));
+        }
+      if (!myBeaconExists)
+        {
+          // If I am not present in neighbor's beacon timing element, this may be caused by collisions with
+          ShiftOwnBeacon (interface);
           return;
         }
     }
 }
+
+void
+PeerManagementProtocol::ShiftOwnBeacon (uint32_t interface)
+{
+  // If beacon interval is equal to the neighbor's one and one o more beacons received
+  // by my neighbor coincide with my beacon - apply random uniformly distributed shift from
+  // [-m_maxBeaconShift, m_maxBeaconShift] except 0.
+  UniformVariable beaconShift (-m_maxBeaconShift, m_maxBeaconShift);
+  int shift = 0;
+  do
+    {
+      shift = (int) beaconShift.GetValue ();
+    }
+  while (shift == 0);
+  // Apply beacon shift parameters:
+  PeerManagementProtocolMacMap::iterator plugin = m_plugins.find (interface);
+  NS_ASSERT (plugin != m_plugins.end ());
+  plugin->second->SetBeaconShift (TuToTime (shift));
+}
+
 Time
-PeerManagementProtocol::TuToTime (uint32_t x)
+PeerManagementProtocol::TuToTime (int x)
 {
   return MicroSeconds (x * 1024);
 }
-uint32_t
+int
 PeerManagementProtocol::TimeToTu (Time x)
 {
-  return (uint32_t)(x.GetMicroSeconds () / 1024);
+  return (int)(x.GetMicroSeconds () / 1024);
 }
 
 void
@@ -522,6 +537,7 @@
 PeerManagementProtocol::NotifyBeaconSent (uint32_t interface, Time beaconInterval)
 {
   m_lastBeacon[interface] = Simulator::Now ();
+  Simulator::Schedule (beaconInterval - TuToTime (m_maxBeaconShift + 1), &PeerManagementProtocol::CheckBeaconCollisions,this, interface);
   m_beaconInterval[interface] = beaconInterval;
 }
 PeerManagementProtocol::Statistics::Statistics (uint16_t t) :
--- a/src/mesh/model/dot11s/peer-management-protocol.h	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/mesh/model/dot11s/peer-management-protocol.h	Fri Dec 16 18:51:18 2011 +0100
@@ -82,7 +82,7 @@
    * \param beaconTiming beacon timing element (needed by BCA)
    */
   void ReceiveBeacon (uint32_t interface, Mac48Address peerAddress, Time beaconInterval, Ptr<IeBeaconTiming> beaconTiming);
-  //\}
+  // \}
   /**
    * \brief Methods that handle Peer link management frames
    * interaction:
@@ -125,9 +125,9 @@
    * \brief Checks if there is established link
    */
   bool IsActiveLink (uint32_t interface, Mac48Address peerAddress);
-  //\}
+  // \}
   ///\name Interface to other protocols (MLME)
-  //\{
+  // \{
   /// Set peer link status change callback
   void SetPeerLinkStatusCallback (Callback<void, Mac48Address, Mac48Address, uint32_t, bool> cb);
   /// Find active peer link by my interface and peer interface MAC
@@ -150,7 +150,8 @@
   void Report (std::ostream &) const;
   void ResetStats ();
 private:
-  /** \name Private structures
+  /**
+   * \name Private structures
    * \{
    */
   /// Keeps information about beacon of peer station: beacon interval, association ID, last time we have received a beacon
@@ -171,7 +172,7 @@
   typedef std::map<uint32_t, BeaconsOnInterface> BeaconInfoMap;
   ///\brief this vector keeps pointers to MAC-plugins
   typedef std::map<uint32_t, Ptr<PeerManagementProtocolMac> > PeerManagementProtocolMacMap;
-  ///\}
+  // \}
 private:
   PeerManagementProtocol& operator= (const PeerManagementProtocol &);
   PeerManagementProtocol (const PeerManagementProtocol &);
@@ -193,14 +194,15 @@
    */
   void PeerLinkStatus (uint32_t interface, Mac48Address peerAddress, Mac48Address peerMeshPointAddres, PeerLink::PeerState ostate, PeerLink::PeerState nstate);
   ///\brief BCA
-  void DoShiftBeacon (uint32_t interface);
+  void CheckBeaconCollisions (uint32_t interface);
+  void ShiftOwnBeacon (uint32_t interface);
   /**
    * \name Time<-->TU converters:
    * \{
    */
-  Time TuToTime (uint32_t x);
-  uint32_t TimeToTu (Time x);
-  ///\}
+  Time TuToTime (int x);
+  int TimeToTu (Time x);
+  // \}
 
   /// Aux. method to register open links
   void NotifyLinkOpen (Mac48Address peerMp, Mac48Address peerIface, Mac48Address myIface, uint32_t interface);
@@ -218,9 +220,9 @@
   bool m_enableBca;
   /// Beacon can be shifted at [-m_maxBeaconShift; +m_maxBeaconShift] TUs
   uint16_t m_maxBeaconShift;
-  ///Last beacon at each interface
+  /// Last beacon at each interface
   std::map<uint32_t, Time> m_lastBeacon;
-  ///Beacon interval at each interface
+  /// Beacon interval at each interface
   std::map<uint32_t, Time> m_beaconInterval;
 
   /**
@@ -248,7 +250,7 @@
   LinkEventCallback m_linkCloseTraceSrc;
 
   ///\name Statistics:
-  ///\{
+  // \{
   struct Statistics {
     uint16_t linksTotal;
     uint16_t linksOpened;
@@ -258,7 +260,7 @@
     void Print (std::ostream & os) const;
   };
   struct Statistics m_stats;
-  ///\}
+  // \}
 };
 
 } // namespace dot11s
--- a/src/mesh/model/mesh-wifi-beacon.h	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/mesh/model/mesh-wifi-beacon.h	Fri Dec 16 18:51:18 2011 +0100
@@ -58,7 +58,7 @@
    * \param mpAddress is mesh point address
    */
   WifiMacHeader CreateHeader (Mac48Address address, Mac48Address mpAddress);
-  ///Returns a beacon interval of wifi beacon
+  /// Returns a beacon interval of wifi beacon
   Time GetBeaconInterval () const;
   /// Create frame = { beacon header + all information elements sorted by ElementId () }
   Ptr<Packet> CreatePacket ();
--- a/src/mesh/model/mesh-wifi-interface-mac.cc	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/mesh/model/mesh-wifi-interface-mac.cc	Fri Dec 16 18:51:18 2011 +0100
@@ -379,7 +379,6 @@
   NS_LOG_DEBUG (GetAddress () << " is sending beacon");
 
   NS_ASSERT (!m_beaconSendEvent.IsRunning ());
-  NS_ASSERT (Simulator::Now ().GetMicroSeconds () == GetTbtt ().GetMicroSeconds ()); // assert that beacon is just on time
 
   // Form & send beacon
   MeshWifiBeacon beacon (GetSsid (), GetSupportedRates (), m_beaconInterval.GetMicroSeconds ());
--- a/src/mesh/model/mesh-wifi-interface-mac.h	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/mesh/model/mesh-wifi-interface-mac.h	Fri Dec 16 18:51:18 2011 +0100
@@ -61,19 +61,19 @@
   virtual ~MeshWifiInterfaceMac ();
 
   ///\name Inherited from WifiMac
-  //\{
+  // \{
   virtual void  Enqueue (Ptr<const Packet> packet, Mac48Address to, Mac48Address from);
   virtual void  Enqueue (Ptr<const Packet> packet, Mac48Address to);
   virtual bool  SupportsSendFrom () const;
   virtual void  SetLinkUpCallback (Callback<void> linkUp);
-  //\}
+  // \}
   ///\name Each mesh point interfaces must know the mesh point address
-  //\{
+  // \{
   void SetMeshPointAddress (Mac48Address);
   Mac48Address GetMeshPointAddress () const;
-  //\}
+  // \}
   ///\name Beacons
-  //\{
+  // \{
   /// Set maximum initial random delay before first beacon
   void SetRandomStartDelay (Time interval);
   /// Set interval between two successive beacons
@@ -94,13 +94,13 @@
    * \attention User of ShiftTbtt () must take care to not shift it to the past.
    */
   void ShiftTbtt (Time shift);
-  //\}
+  // \}
 
   ///\name Plugins
-  //\{
+  // \{
   /// Install plugin. TODO return unique ID to allow unregister plugins
   void InstallPlugin (Ptr<MeshWifiInterfaceMacPlugin> plugin);
-  //\}
+  // \}
 
   /** \name Channel switching
    *
@@ -109,12 +109,12 @@
    *
    * Number of channels to use must be limited elsewhere.
    */
-  //\{
+  // \{
   /// Current channel Id
   uint16_t GetFrequencyChannel () const;
   /// Switch channel
   void SwitchFrequencyChannel (uint16_t new_id);
-  //\}
+  // \}
 
   /// To be used by plugins sending management frames.
   void SendManagementFrame (Ptr<Packet> frame, const WifiMacHeader& hdr);
@@ -122,11 +122,11 @@
   bool CheckSupportedRates (SupportedRates rates) const;
   /// \return list of supported bitrates
   SupportedRates GetSupportedRates () const;
-  ///\ name Metric Calculation routines:
-  ///\{
+  ///\name Metric Calculation routines:
+  // \{
   void SetLinkMetricCallback (Callback<uint32_t, Mac48Address, Ptr<MeshWifiInterfaceMac> > cb);
   uint32_t GetLinkMetric (Mac48Address peerAddress);
-  ///\}
+  // \}
   ///\brief Statistics:
   void Report (std::ostream &) const;
   void ResetStats ();
@@ -152,14 +152,14 @@
   typedef std::vector<Ptr<MeshWifiInterfaceMacPlugin> > PluginList;
 
   ///\name Mesh timing intervals
-  //\{
+  // \{
   /// Beaconing interval.
   Time m_beaconInterval;
   /// Maximum delay before first beacon
   Time m_randomStart;
   /// Time for the next frame
   Time m_tbtt;
-  //\}
+  // \}
 
   /// Mesh point address
   Mac48Address m_mpAddress;
@@ -170,7 +170,7 @@
   PluginList m_plugins;
   Callback<uint32_t, Mac48Address, Ptr<MeshWifiInterfaceMac> > m_linkMetricCallback;
   ///\name Statistics:
-  ///\{
+  // \{
   struct Statistics
   {
     uint16_t recvBeacons;
@@ -183,7 +183,7 @@
     Statistics ();
   };
   Statistics m_stats;
-  ///\}
+  // \}
   /// Current PHY standard: needed to configure metric
   WifiPhyStandard m_standard;
 };
Binary file src/mesh/test/dot11s/hwmp-proactive-regression-test-0-1.pcap has changed
Binary file src/mesh/test/dot11s/hwmp-proactive-regression-test-1-1.pcap has changed
Binary file src/mesh/test/dot11s/hwmp-proactive-regression-test-2-1.pcap has changed
Binary file src/mesh/test/dot11s/hwmp-proactive-regression-test-3-1.pcap has changed
Binary file src/mesh/test/dot11s/hwmp-proactive-regression-test-4-1.pcap has changed
Binary file src/mesh/test/dot11s/hwmp-reactive-regression-test-0-1.pcap has changed
Binary file src/mesh/test/dot11s/hwmp-reactive-regression-test-1-1.pcap has changed
Binary file src/mesh/test/dot11s/hwmp-reactive-regression-test-2-1.pcap has changed
Binary file src/mesh/test/dot11s/hwmp-reactive-regression-test-3-1.pcap has changed
Binary file src/mesh/test/dot11s/hwmp-reactive-regression-test-4-1.pcap has changed
Binary file src/mesh/test/dot11s/hwmp-reactive-regression-test-5-1.pcap has changed
Binary file src/mesh/test/dot11s/hwmp-simplest-regression-test-0-1.pcap has changed
Binary file src/mesh/test/dot11s/hwmp-simplest-regression-test-1-1.pcap has changed
Binary file src/mesh/test/dot11s/hwmp-target-flags-regression-test-0-1.pcap has changed
Binary file src/mesh/test/dot11s/hwmp-target-flags-regression-test-1-1.pcap has changed
Binary file src/mesh/test/dot11s/hwmp-target-flags-regression-test-2-1.pcap has changed
Binary file src/mesh/test/dot11s/hwmp-target-flags-regression-test-3-1.pcap has changed
--- a/src/mobility/bindings/modulegen__gcc_ILP32.py	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/mobility/bindings/modulegen__gcc_ILP32.py	Fri Dec 16 18:51:18 2011 +0100
@@ -2933,6 +2933,11 @@
                    'ns3::Vector', 
                    [], 
                    is_const=True)
+    ## mobility-model.h (module 'mobility'): double ns3::MobilityModel::GetRelativeSpeed(ns3::Ptr<const ns3::MobilityModel> other) const [member function]
+    cls.add_method('GetRelativeSpeed', 
+                   'double', 
+                   [param('ns3::Ptr< ns3::MobilityModel const >', 'other')], 
+                   is_const=True)
     ## mobility-model.h (module 'mobility'): static ns3::TypeId ns3::MobilityModel::GetTypeId() [member function]
     cls.add_method('GetTypeId', 
                    'ns3::TypeId', 
--- a/src/mobility/bindings/modulegen__gcc_LP64.py	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/mobility/bindings/modulegen__gcc_LP64.py	Fri Dec 16 18:51:18 2011 +0100
@@ -2933,6 +2933,11 @@
                    'ns3::Vector', 
                    [], 
                    is_const=True)
+    ## mobility-model.h (module 'mobility'): double ns3::MobilityModel::GetRelativeSpeed(ns3::Ptr<const ns3::MobilityModel> other) const [member function]
+    cls.add_method('GetRelativeSpeed', 
+                   'double', 
+                   [param('ns3::Ptr< ns3::MobilityModel const >', 'other')], 
+                   is_const=True)
     ## mobility-model.h (module 'mobility'): static ns3::TypeId ns3::MobilityModel::GetTypeId() [member function]
     cls.add_method('GetTypeId', 
                    'ns3::TypeId', 
--- a/src/mobility/helper/ns2-mobility-helper.cc	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/mobility/helper/ns2-mobility-helper.cc	Fri Dec 16 18:51:18 2011 +0100
@@ -23,7 +23,7 @@
  * Brief description: Implementation of a ns2 movement trace file reader.
  *
  * This implementation is based on the ns2 movement documentation of ns2
- * as described in http://www.isi.edu/nsnam/ns/doc/node174.html
+ * as described in http://www.isi.edu/nsnam/ns/doc/node172.html
  *
  * Valid trace files use the following ns2 statements:
  *
@@ -353,6 +353,10 @@
     {
       string x;
       s >> x;
+      if (x.length () == 0)
+        {
+          continue;
+        }
       ret.tokens.push_back (x);
       int ii (0);
       double d (0);
@@ -638,6 +642,10 @@
       // first calculate the time; time = distance / speed
       double time = sqrt (pow (xFinalPosition - retval.m_finalPosition.x, 2) + pow (yFinalPosition - retval.m_finalPosition.y, 2)) / speed;
       NS_LOG_DEBUG ("at=" << at << " time=" << time);
+      if (time == 0)
+        {
+          return retval;
+        }
       // now calculate the xSpeed = distance / time
       double xSpeed = (xFinalPosition - retval.m_finalPosition.x) / time;
       double ySpeed = (yFinalPosition - retval.m_finalPosition.y) / time; // & same with ySpeed
@@ -649,10 +657,7 @@
       NS_LOG_DEBUG ("Calculated Speed: X=" << xSpeed << " Y=" << ySpeed << " Z=" << zSpeed);
 
       // Set the Values
-      if (time >= 0)
-        {
-          Simulator::Schedule (Seconds (at), &ConstantVelocityMobilityModel::SetVelocity, model, Vector (xSpeed, ySpeed, zSpeed));
-        }
+      Simulator::Schedule (Seconds (at), &ConstantVelocityMobilityModel::SetVelocity, model, Vector (xSpeed, ySpeed, zSpeed));
       retval.m_stopEvent = Simulator::Schedule (Seconds (at + time), &ConstantVelocityMobilityModel::SetVelocity, model, Vector (0, 0, 0));
       retval.m_finalPosition.x += xSpeed * time;
       retval.m_finalPosition.y += ySpeed * time;
--- a/src/mobility/helper/ns2-mobility-helper.h	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/mobility/helper/ns2-mobility-helper.h	Fri Dec 16 18:51:18 2011 +0100
@@ -37,7 +37,7 @@
  * \brief Helper class which can read ns-2 movement files and configure nodes mobility.
  * 
  * This implementation is based on the ns2 movement documentation of ns2
- * as described in http://www.isi.edu/nsnam/ns/doc/node174.html
+ * as described in http://www.isi.edu/nsnam/ns/doc/node172.html
  *
  * Valid trace files use the following ns2 statements:
  \verbatim
--- a/src/mobility/model/waypoint-mobility-model.cc	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/mobility/model/waypoint-mobility-model.cc	Fri Dec 16 18:51:18 2011 +0100
@@ -203,7 +203,7 @@
 WaypointMobilityModel::EndMobility (void)
 {
   m_waypoints.clear ();
-  m_current.time = Seconds (std::numeric_limits<double>::infinity ());
+  m_current.time = Time(std::numeric_limits<uint64_t>::infinity());
   m_next.time = m_current.time;
   m_first = true;
 }
--- a/src/mobility/test/ns2-mobility-helper-test-suite.cc	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/mobility/test/ns2-mobility-helper-test-suite.cc	Fri Dec 16 18:51:18 2011 +0100
@@ -432,6 +432,24 @@
     t->AddReferencePoint ("0", 6, Vector (0, 5, 0), Vector (0,  -1, 0));
     t->AddReferencePoint ("0", 16, Vector (0, -10, 0), Vector (0, 0, 0));
     AddTestCase (t);
+    t = new Ns2MobilityHelperTest ("Bug 1059 testcase", Seconds (16));
+    t->SetTrace ("$node_(0) set X_ 10.0\r\n"
+                 "$node_(0) set Y_ 0.0\r\n"
+                 );
+    //                     id  t  position         velocity
+    t->AddReferencePoint ("0", 0, Vector (10, 0, 0), Vector (0,  0, 0));
+    AddTestCase (t);
+    t = new Ns2MobilityHelperTest ("Bug 1301 testcase", Seconds (16));
+    t->SetTrace ("$node_(0) set X_ 10.0\n"
+                 "$node_(0) set Y_ 0.0\n"
+                 "$ns_ at 1.0 \"$node_(0) setdest 10  0       1\"\n"
+                 );
+    //                     id  t  position         velocity
+    // Moving to the current position must change nothing. No NaN
+    // speed must be.
+    t->AddReferencePoint ("0", 0, Vector (10, 0, 0), Vector (0,  0, 0));
+    AddTestCase (t);
+
 
   }
 } g_ns2TransmobilityHelperTestSuite;
--- a/src/netanim/bindings/modulegen__gcc_ILP32.py	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/netanim/bindings/modulegen__gcc_ILP32.py	Fri Dec 16 18:51:18 2011 +0100
@@ -515,6 +515,15 @@
     cls.add_constructor([param('std::string const', 'filename'), param('bool', 'usingXML', default_value='true')])
     ## animation-interface.h (module 'netanim'): ns3::AnimationInterface::AnimationInterface(uint16_t port, bool usingXML=true) [constructor]
     cls.add_constructor([param('uint16_t', 'port'), param('bool', 'usingXML', default_value='true')])
+    ## animation-interface.h (module 'netanim'): static bool ns3::AnimationInterface::IsInitialized() [member function]
+    cls.add_method('IsInitialized', 
+                   'bool', 
+                   [], 
+                   is_static=True)
+    ## animation-interface.h (module 'netanim'): bool ns3::AnimationInterface::IsStarted() [member function]
+    cls.add_method('IsStarted', 
+                   'bool', 
+                   [])
     ## animation-interface.h (module 'netanim'): void ns3::AnimationInterface::ResetAnimWriteCallback() [member function]
     cls.add_method('ResetAnimWriteCallback', 
                    'void', 
@@ -3220,6 +3229,11 @@
                    'ns3::Vector', 
                    [], 
                    is_const=True)
+    ## mobility-model.h (module 'mobility'): double ns3::MobilityModel::GetRelativeSpeed(ns3::Ptr<const ns3::MobilityModel> other) const [member function]
+    cls.add_method('GetRelativeSpeed', 
+                   'double', 
+                   [param('ns3::Ptr< ns3::MobilityModel const >', 'other')], 
+                   is_const=True)
     ## mobility-model.h (module 'mobility'): static ns3::TypeId ns3::MobilityModel::GetTypeId() [member function]
     cls.add_method('GetTypeId', 
                    'ns3::TypeId', 
--- a/src/netanim/bindings/modulegen__gcc_LP64.py	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/netanim/bindings/modulegen__gcc_LP64.py	Fri Dec 16 18:51:18 2011 +0100
@@ -515,6 +515,15 @@
     cls.add_constructor([param('std::string const', 'filename'), param('bool', 'usingXML', default_value='true')])
     ## animation-interface.h (module 'netanim'): ns3::AnimationInterface::AnimationInterface(uint16_t port, bool usingXML=true) [constructor]
     cls.add_constructor([param('uint16_t', 'port'), param('bool', 'usingXML', default_value='true')])
+    ## animation-interface.h (module 'netanim'): static bool ns3::AnimationInterface::IsInitialized() [member function]
+    cls.add_method('IsInitialized', 
+                   'bool', 
+                   [], 
+                   is_static=True)
+    ## animation-interface.h (module 'netanim'): bool ns3::AnimationInterface::IsStarted() [member function]
+    cls.add_method('IsStarted', 
+                   'bool', 
+                   [])
     ## animation-interface.h (module 'netanim'): void ns3::AnimationInterface::ResetAnimWriteCallback() [member function]
     cls.add_method('ResetAnimWriteCallback', 
                    'void', 
@@ -3220,6 +3229,11 @@
                    'ns3::Vector', 
                    [], 
                    is_const=True)
+    ## mobility-model.h (module 'mobility'): double ns3::MobilityModel::GetRelativeSpeed(ns3::Ptr<const ns3::MobilityModel> other) const [member function]
+    cls.add_method('GetRelativeSpeed', 
+                   'double', 
+                   [param('ns3::Ptr< ns3::MobilityModel const >', 'other')], 
+                   is_const=True)
     ## mobility-model.h (module 'mobility'): static ns3::TypeId ns3::MobilityModel::GetTypeId() [member function]
     cls.add_method('GetTypeId', 
                    'ns3::TypeId', 
--- a/src/netanim/model/animation-interface.cc	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/netanim/model/animation-interface.cc	Fri Dec 16 18:51:18 2011 +0100
@@ -51,14 +51,18 @@
 
 NS_LOG_COMPONENT_DEFINE ("AnimationInterface");
 
+#define PURGE_INTERVAL 5
+static bool initialized = false;
+
 namespace ns3 {
 
 AnimationInterface::AnimationInterface ()
   : m_fHandle (STDOUT_FILENO), m_xml (false), mobilitypollinterval (Seconds(0.25)),
     usingSockets (false), mport (0), outputfilename (""),
     OutputFileSet (false), ServerPortSet (false), gAnimUid (0),randomPosition (true),
-    m_writeCallback (0)
+    m_writeCallback (0), m_started (false)
 {
+  initialized = true;
   StartAnimation ();
 }
 
@@ -66,8 +70,9 @@
   : m_fHandle (STDOUT_FILENO), m_xml (usingXML), mobilitypollinterval (Seconds(0.25)), 
     usingSockets (false), mport (0), outputfilename (fn),
     OutputFileSet (false), ServerPortSet (false), gAnimUid (0), randomPosition (true),
-    m_writeCallback (0)
+    m_writeCallback (0), m_started (false)
 {
+  initialized = true;
   StartAnimation ();
 }
 
@@ -75,8 +80,9 @@
   : m_fHandle (STDOUT_FILENO), m_xml (usingXML), mobilitypollinterval (Seconds(0.25)), 
     usingSockets (true), mport (port), outputfilename (""),
     OutputFileSet (false), ServerPortSet (false), gAnimUid (0), randomPosition (true),
-    m_writeCallback (0)
+    m_writeCallback (0), m_started (false)
 {
+  initialized = true;
   StartAnimation ();
 }
 
@@ -116,6 +122,17 @@
   return true;
 }
 
+bool AnimationInterface::IsInitialized ()
+{
+  return initialized;
+}
+
+bool AnimationInterface::IsStarted ()
+{
+  return m_started;
+
+}
+
 void AnimationInterface::SetAnimWriteCallback (AnimWriteCallback cb)
 {
   m_writeCallback = cb;
@@ -226,8 +243,90 @@
   return nodeLocation[n->GetId ()];
 }
 
+void AnimationInterface::PurgePendingWifi ()
+{
+  if (pendingWifiPackets.empty ())
+    return;
+  std::vector <uint64_t> purgeList;
+  for (std::map<uint64_t, AnimPacketInfo>::iterator i = pendingWifiPackets.begin ();
+       i != pendingWifiPackets.end ();
+       ++i)
+    {
+     
+      AnimPacketInfo pktInfo = i->second; 
+      double delta = (Simulator::Now ().GetSeconds () - pktInfo.m_fbTx);
+      if (delta > PURGE_INTERVAL)
+        {
+          purgeList.push_back (i->first);
+        }
+    }
+
+  for (std::vector <uint64_t>::iterator i = purgeList.begin ();
+       i != purgeList.end ();
+       ++i)
+    {
+      pendingWifiPackets.erase (*i);
+    }
+
+}
+
+void AnimationInterface::PurgePendingWimax ()
+{
+  if (pendingWimaxPackets.empty ())
+    return;
+  std::vector <uint64_t> purgeList;
+  for (std::map<uint64_t, AnimPacketInfo>::iterator i = pendingWimaxPackets.begin ();
+       i != pendingWimaxPackets.end ();
+       ++i)
+    {
+
+      AnimPacketInfo pktInfo = i->second;
+      double delta = (Simulator::Now ().GetSeconds () - pktInfo.m_fbTx);
+      if (delta > PURGE_INTERVAL)
+        {
+          purgeList.push_back (i->first);
+        }
+    }
+
+  for (std::vector <uint64_t>::iterator i = purgeList.begin ();
+       i != purgeList.end ();
+       ++i)
+    {
+      pendingWimaxPackets.erase (*i);
+    }
+
+}
+
+void AnimationInterface::PurgePendingCsma ()
+{
+  if (pendingCsmaPackets.empty ())
+    return;
+  std::vector <uint64_t> purgeList;
+  for (std::map<uint64_t, AnimPacketInfo>::iterator i = pendingCsmaPackets.begin ();
+       i != pendingCsmaPackets.end ();
+       ++i)
+    {
+    
+      AnimPacketInfo pktInfo = i->second;
+      double delta = (Simulator::Now ().GetSeconds () - pktInfo.m_fbTx);
+      if (delta > PURGE_INTERVAL)
+        { 
+          purgeList.push_back (i->first);
+        }
+    }
+
+  for (std::vector <uint64_t>::iterator i = purgeList.begin ();
+       i != purgeList.end ();
+       ++i)
+    {
+      pendingCsmaPackets.erase (*i);
+    }
+
+}
+
 void AnimationInterface::StartAnimation ()
 {
+  m_started = true;
   if (usingSockets)
     {
       SetServerPort (mport);
@@ -259,7 +358,7 @@
       std::ostringstream oss;
       oss << GetXMLOpen_anim (0);
       oss << GetPreamble ();
-      oss << GetXMLOpen_topology (topo_minX,topo_minY,topo_maxX,topo_maxY);
+      oss << GetXMLOpen_topology (topo_minX, topo_minY, topo_maxX, topo_maxY);
       WriteN (m_fHandle, oss.str ());
     }
   NS_LOG_INFO ("Setting topology for "<<NodeList::GetNNodes ()<<" Nodes");
@@ -271,7 +370,7 @@
       if (m_xml)
         {
           Vector v = GetPosition (n);
-          oss << GetXMLOpenClose_node (0,n->GetId (),v.x,v.y);
+          oss << GetXMLOpenClose_node (0, n->GetId (), v.x, v.y);
 	  WriteN (m_fHandle, oss.str ());
         }
       else
@@ -336,6 +435,11 @@
       Simulator::Schedule (mobilitypollinterval, &AnimationInterface::MobilityAutoCheck, this);
     }
 
+  ConnectCallbacks ();
+}
+
+void AnimationInterface::ConnectCallbacks ()
+{
   // Connect the callbacks
   Config::Connect ("/ChannelList/*/TxRxPointToPoint",
                    MakeCallback (&AnimationInterface::DevTxTrace, this));
@@ -365,11 +469,12 @@
                    MakeCallback (&AnimationInterface::CsmaMacRxTrace, this));
 
 
+}
 
-}
 
 void AnimationInterface::StopAnimation ()
 {
+  m_started = false;
   NS_LOG_INFO ("Stopping Animation");
   ResetAnimWriteCallback ();
   if (m_fHandle > 0) 
@@ -510,6 +615,8 @@
                                      Ptr<NetDevice> tx, Ptr<NetDevice> rx,
                                      Time txTime, Time rxTime)
 {
+  if (!m_started)
+    return;
   NS_ASSERT (tx);
   NS_ASSERT (rx);
   Time now = Simulator::Now ();
@@ -586,6 +693,8 @@
 void AnimationInterface::WifiPhyTxBeginTrace (std::string context,
                                           Ptr<const Packet> p)
 {
+  if (!m_started)
+    return;
   Ptr <NetDevice> ndev = GetNetDeviceFromContext (context); 
   NS_ASSERT (ndev);
   Ptr <Node> n = ndev->GetNode ();
@@ -608,6 +717,8 @@
 void AnimationInterface::WifiPhyTxDropTrace (std::string context,
                                              Ptr<const Packet> p)
 {
+  if (!m_started)
+    return;
   Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
   NS_ASSERT (ndev);
   // Erase pending wifi
@@ -621,6 +732,8 @@
 void AnimationInterface::WifiPhyRxBeginTrace (std::string context,
                                               Ptr<const Packet> p)
 {
+  if (!m_started)
+    return;
   Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
   NS_ASSERT (ndev);
   uint64_t AnimUid = GetAnimUidFromPacket (p);
@@ -638,6 +751,8 @@
 void AnimationInterface::WifiPhyRxEndTrace (std::string context,
                                             Ptr<const Packet> p)
 {
+  if (!m_started)
+    return;
   Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
   NS_ASSERT (ndev);
   Ptr <Node> n = ndev->GetNode ();
@@ -656,6 +771,8 @@
 void AnimationInterface::WifiMacRxTrace (std::string context,
                                          Ptr<const Packet> p)
 {
+  if (!m_started)
+    return;
   Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
   NS_ASSERT (ndev);
   Ptr <Node> n = ndev->GetNode ();
@@ -673,7 +790,6 @@
     {
       NS_LOG_INFO ("MacRxTrace for packet:" << AnimUid << " complete");
       OutputWirelessPacket (pktInfo, pktrxInfo);
-      pktInfo.RemoveRxInfo (ndev);
     }
 
 }
@@ -684,6 +800,8 @@
 
 void AnimationInterface::WimaxTxTrace (std::string context, Ptr<const Packet> p, const Mac48Address & m)
 {
+  if (!m_started)
+    return;
   Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
   NS_ASSERT (ndev);
   Ptr <Node> n = ndev->GetNode ();
@@ -701,6 +819,8 @@
 
 void AnimationInterface::WimaxRxTrace (std::string context, Ptr<const Packet> p, const Mac48Address & m)
 {
+  if (!m_started)
+    return;
   Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
   NS_ASSERT (ndev);
   Ptr <Node> n = ndev->GetNode ();
@@ -717,6 +837,8 @@
 
 void AnimationInterface::CsmaPhyTxBeginTrace (std::string context, Ptr<const Packet> p)
 {
+  if (!m_started)
+    return;
   Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
   NS_ASSERT (ndev);
   Ptr <Node> n = ndev->GetNode ();
@@ -733,6 +855,8 @@
 
 void AnimationInterface::CsmaPhyTxEndTrace (std::string context, Ptr<const Packet> p)
 {
+  if (!m_started)
+    return;
   Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
   NS_ASSERT (ndev);
   uint64_t AnimUid = GetAnimUidFromPacket (p);
@@ -749,6 +873,8 @@
 
 void AnimationInterface::CsmaPhyRxEndTrace (std::string context, Ptr<const Packet> p)
 {
+  if (!m_started)
+    return;
   Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
   NS_ASSERT (ndev);
   Ptr <Node> n = ndev->GetNode ();
@@ -770,6 +896,8 @@
 void AnimationInterface::CsmaMacRxTrace (std::string context,
                                          Ptr<const Packet> p)
 {
+  if (!m_started)
+    return;
   NS_LOG_FUNCTION (this);
   Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
   NS_ASSERT (ndev);
@@ -788,7 +916,6 @@
     {
       NS_LOG_INFO ("MacRxTrace for packet:" << AnimUid << " complete");
       OutputCsmaPacket (pktInfo, pktrxInfo);
-      pktInfo.RemoveRxInfo (ndev);
     }
 }
 
@@ -796,6 +923,8 @@
 void AnimationInterface::MobilityCourseChangeTrace (Ptr <const MobilityModel> mobility)
 
 {
+  if (!m_started)
+    return;
   Ptr <Node> n = mobility->GetObject <Node> ();
   NS_ASSERT (n);
   Vector v ;
@@ -820,8 +949,8 @@
 bool AnimationInterface::NodeHasMoved (Ptr <Node> n, Vector newLocation)
 {
   Vector oldLocation = GetPosition (n);
-  if ((ceil(oldLocation.x) == ceil(newLocation.x)) &&
-    (ceil(oldLocation.y) == ceil(newLocation.y)))
+  if ((ceil (oldLocation.x) == ceil (newLocation.x)) &&
+    (ceil (oldLocation.y) == ceil (newLocation.y)))
     {
      
       return false;
@@ -836,19 +965,22 @@
 {
   std::vector <Ptr <Node> > MovedNodes = RecalcTopoBounds ();
   std::ostringstream oss;
-  oss << GetXMLOpen_topology (topo_minX,topo_minY,topo_maxX,topo_maxY);
+  oss << GetXMLOpen_topology (topo_minX, topo_minY, topo_maxX, topo_maxY);
   for (uint32_t i = 0; i < MovedNodes.size (); i++)
     {
       Ptr <Node> n = MovedNodes [i];
       NS_ASSERT (n);
       Vector v = GetPosition (n);
-      oss << GetXMLOpenClose_node (0,n->GetId (), v.x, v.y);
+      oss << GetXMLOpenClose_node (0, n->GetId (), v.x, v.y);
     }
   oss << GetXMLClose ("topology");
   WriteN (m_fHandle, oss.str ());
   WriteDummyPacket ();
   if (!Simulator::IsFinished ())
     {
+      PurgePendingWifi ();
+      PurgePendingWimax ();
+      PurgePendingCsma ();
       Simulator::Schedule (mobilitypollinterval, &AnimationInterface::MobilityAutoCheck, this);
     }
 }
--- a/src/netanim/model/animation-interface.h	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/netanim/model/animation-interface.h	Fri Dec 16 18:51:18 2011 +0100
@@ -99,6 +99,13 @@
   AnimationInterface (uint16_t port, bool usingXML = true);
 
   /**
+   * \brief Check if AnimationInterface is initialized
+   * \returns true if AnimationInterface was already initialized
+   *
+   */
+  static bool IsInitialized (void);
+
+  /**
    * \brief Specify that animation commands are to be written
    * to the specified output file.
    *
@@ -203,6 +210,13 @@
    */
   void SetConstantPosition (Ptr <Node> n, double x, double y, double z=0);
 
+  /**
+   * \brief Is AnimationInterface started
+   * \returns true if AnimationInterface was started
+   *
+   */
+  bool IsStarted (void);
+
 private:
 #ifndef WIN32
   int m_fHandle;  // File handle for output (-1 if none)
@@ -286,12 +300,19 @@
   bool NodeHasMoved (Ptr <Node> n, Vector newLocation);
   void AddMargin ();
 
+  void PurgePendingWifi ();
+  void PurgePendingWimax ();
+  void PurgePendingCsma ();
+
   // Recalculate topology bounds
   void RecalcTopoBounds (Vector v);
   std::vector < Ptr <Node> > RecalcTopoBounds ();
 
   bool randomPosition;
   AnimWriteCallback m_writeCallback;
+  void ConnectCallbacks ();
+
+  bool m_started;
 
   // Path helper
   std::vector<std::string> GetElementsFromContext (std::string context);
--- a/src/network/bindings/modulegen__gcc_ILP32.py	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/network/bindings/modulegen__gcc_ILP32.py	Fri Dec 16 18:51:18 2011 +0100
@@ -222,6 +222,14 @@
     module.add_enum('', ['FRAME_FLAG_NONE', 'FRAME_FLAG_CFP', 'FRAME_FLAG_SHORT_PREAMBLE', 'FRAME_FLAG_WEP', 'FRAME_FLAG_FRAGMENTED', 'FRAME_FLAG_FCS_INCLUDED', 'FRAME_FLAG_DATA_PADDING', 'FRAME_FLAG_BAD_FCS', 'FRAME_FLAG_SHORT_GUARD'], outer_class=root_module['ns3::RadiotapHeader'])
     ## radiotap-header.h (module 'network'): ns3::RadiotapHeader [enumeration]
     module.add_enum('', ['CHANNEL_FLAG_NONE', 'CHANNEL_FLAG_TURBO', 'CHANNEL_FLAG_CCK', 'CHANNEL_FLAG_OFDM', 'CHANNEL_FLAG_SPECTRUM_2GHZ', 'CHANNEL_FLAG_SPECTRUM_5GHZ', 'CHANNEL_FLAG_PASSIVE', 'CHANNEL_FLAG_DYNAMIC', 'CHANNEL_FLAG_GFSK'], outer_class=root_module['ns3::RadiotapHeader'])
+    ## red-queue.h (module 'network'): ns3::RedQueue [class]
+    module.add_class('RedQueue', parent=root_module['ns3::Queue'])
+    ## red-queue.h (module 'network'): ns3::RedQueue [enumeration]
+    module.add_enum('', ['DTYPE_NONE', 'DTYPE_FORCED', 'DTYPE_UNFORCED'], outer_class=root_module['ns3::RedQueue'])
+    ## red-queue.h (module 'network'): ns3::RedQueue::Mode [enumeration]
+    module.add_enum('Mode', ['ILLEGAL', 'PACKETS', 'BYTES'], outer_class=root_module['ns3::RedQueue'])
+    ## red-queue.h (module 'network'): ns3::RedQueue::Stats [struct]
+    module.add_class('Stats', outer_class=root_module['ns3::RedQueue'])
     ## simple-ref-count.h (module 'core'): ns3::SimpleRefCount<ns3::AttributeAccessor, ns3::empty, ns3::DefaultDeleter<ns3::AttributeAccessor> > [class]
     module.add_class('SimpleRefCount', automatic_type_narrowing=True, import_from_module='ns.core', template_parameters=['ns3::AttributeAccessor', 'ns3::empty', 'ns3::DefaultDeleter<ns3::AttributeAccessor>'], parent=root_module['ns3::empty'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
     ## simple-ref-count.h (module 'core'): ns3::SimpleRefCount<ns3::AttributeChecker, ns3::empty, ns3::DefaultDeleter<ns3::AttributeChecker> > [class]
@@ -280,6 +288,10 @@
     module.add_class('AttributeChecker', allow_subclassing=False, automatic_type_narrowing=True, import_from_module='ns.core', parent=root_module['ns3::SimpleRefCount< ns3::AttributeChecker, ns3::empty, ns3::DefaultDeleter<ns3::AttributeChecker> >'])
     ## attribute.h (module 'core'): ns3::AttributeValue [class]
     module.add_class('AttributeValue', allow_subclassing=False, automatic_type_narrowing=True, import_from_module='ns.core', parent=root_module['ns3::SimpleRefCount< ns3::AttributeValue, ns3::empty, ns3::DefaultDeleter<ns3::AttributeValue> >'])
+    ## boolean.h (module 'core'): ns3::BooleanChecker [class]
+    module.add_class('BooleanChecker', import_from_module='ns.core', parent=root_module['ns3::AttributeChecker'])
+    ## boolean.h (module 'core'): ns3::BooleanValue [class]
+    module.add_class('BooleanValue', import_from_module='ns.core', parent=root_module['ns3::AttributeValue'])
     ## callback.h (module 'core'): ns3::CallbackChecker [class]
     module.add_class('CallbackChecker', import_from_module='ns.core', parent=root_module['ns3::AttributeChecker'])
     ## callback.h (module 'core'): ns3::CallbackImplBase [class]
@@ -520,6 +532,8 @@
     register_Ns3PcapFileWrapper_methods(root_module, root_module['ns3::PcapFileWrapper'])
     register_Ns3Queue_methods(root_module, root_module['ns3::Queue'])
     register_Ns3RadiotapHeader_methods(root_module, root_module['ns3::RadiotapHeader'])
+    register_Ns3RedQueue_methods(root_module, root_module['ns3::RedQueue'])
+    register_Ns3RedQueueStats_methods(root_module, root_module['ns3::RedQueue::Stats'])
     register_Ns3SimpleRefCount__Ns3AttributeAccessor_Ns3Empty_Ns3DefaultDeleter__lt__ns3AttributeAccessor__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::AttributeAccessor, ns3::empty, ns3::DefaultDeleter<ns3::AttributeAccessor> >'])
     register_Ns3SimpleRefCount__Ns3AttributeChecker_Ns3Empty_Ns3DefaultDeleter__lt__ns3AttributeChecker__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::AttributeChecker, ns3::empty, ns3::DefaultDeleter<ns3::AttributeChecker> >'])
     register_Ns3SimpleRefCount__Ns3AttributeValue_Ns3Empty_Ns3DefaultDeleter__lt__ns3AttributeValue__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::AttributeValue, ns3::empty, ns3::DefaultDeleter<ns3::AttributeValue> >'])
@@ -545,6 +559,8 @@
     register_Ns3AttributeAccessor_methods(root_module, root_module['ns3::AttributeAccessor'])
     register_Ns3AttributeChecker_methods(root_module, root_module['ns3::AttributeChecker'])
     register_Ns3AttributeValue_methods(root_module, root_module['ns3::AttributeValue'])
+    register_Ns3BooleanChecker_methods(root_module, root_module['ns3::BooleanChecker'])
+    register_Ns3BooleanValue_methods(root_module, root_module['ns3::BooleanValue'])
     register_Ns3CallbackChecker_methods(root_module, root_module['ns3::CallbackChecker'])
     register_Ns3CallbackImplBase_methods(root_module, root_module['ns3::CallbackImplBase'])
     register_Ns3CallbackValue_methods(root_module, root_module['ns3::CallbackValue'])
@@ -4129,6 +4145,70 @@
                    [param('uint64_t', 'tsft')])
     return
 
+def register_Ns3RedQueue_methods(root_module, cls):
+    ## red-queue.h (module 'network'): ns3::RedQueue::RedQueue(ns3::RedQueue const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::RedQueue const &', 'arg0')])
+    ## red-queue.h (module 'network'): ns3::RedQueue::RedQueue() [constructor]
+    cls.add_constructor([])
+    ## red-queue.h (module 'network'): ns3::RedQueue::Mode ns3::RedQueue::GetMode() [member function]
+    cls.add_method('GetMode', 
+                   'ns3::RedQueue::Mode', 
+                   [])
+    ## red-queue.h (module 'network'): uint32_t ns3::RedQueue::GetQueueSize() [member function]
+    cls.add_method('GetQueueSize', 
+                   'uint32_t', 
+                   [])
+    ## red-queue.h (module 'network'): ns3::RedQueue::Stats ns3::RedQueue::GetStats() [member function]
+    cls.add_method('GetStats', 
+                   'ns3::RedQueue::Stats', 
+                   [])
+    ## red-queue.h (module 'network'): static ns3::TypeId ns3::RedQueue::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## red-queue.h (module 'network'): void ns3::RedQueue::SetMode(ns3::RedQueue::Mode mode) [member function]
+    cls.add_method('SetMode', 
+                   'void', 
+                   [param('ns3::RedQueue::Mode', 'mode')])
+    ## red-queue.h (module 'network'): void ns3::RedQueue::SetQueueLimit(uint32_t lim) [member function]
+    cls.add_method('SetQueueLimit', 
+                   'void', 
+                   [param('uint32_t', 'lim')])
+    ## red-queue.h (module 'network'): void ns3::RedQueue::SetTh(double minTh, double maxTh) [member function]
+    cls.add_method('SetTh', 
+                   'void', 
+                   [param('double', 'minTh'), param('double', 'maxTh')])
+    ## red-queue.h (module 'network'): ns3::Ptr<ns3::Packet> ns3::RedQueue::DoDequeue() [member function]
+    cls.add_method('DoDequeue', 
+                   'ns3::Ptr< ns3::Packet >', 
+                   [], 
+                   visibility='private', is_virtual=True)
+    ## red-queue.h (module 'network'): bool ns3::RedQueue::DoEnqueue(ns3::Ptr<ns3::Packet> p) [member function]
+    cls.add_method('DoEnqueue', 
+                   'bool', 
+                   [param('ns3::Ptr< ns3::Packet >', 'p')], 
+                   visibility='private', is_virtual=True)
+    ## red-queue.h (module 'network'): ns3::Ptr<const ns3::Packet> ns3::RedQueue::DoPeek() const [member function]
+    cls.add_method('DoPeek', 
+                   'ns3::Ptr< ns3::Packet const >', 
+                   [], 
+                   is_const=True, visibility='private', is_virtual=True)
+    return
+
+def register_Ns3RedQueueStats_methods(root_module, cls):
+    ## red-queue.h (module 'network'): ns3::RedQueue::Stats::Stats() [constructor]
+    cls.add_constructor([])
+    ## red-queue.h (module 'network'): ns3::RedQueue::Stats::Stats(ns3::RedQueue::Stats const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::RedQueue::Stats const &', 'arg0')])
+    ## red-queue.h (module 'network'): ns3::RedQueue::Stats::forcedDrop [variable]
+    cls.add_instance_attribute('forcedDrop', 'uint32_t', is_const=False)
+    ## red-queue.h (module 'network'): ns3::RedQueue::Stats::qLimDrop [variable]
+    cls.add_instance_attribute('qLimDrop', 'uint32_t', is_const=False)
+    ## red-queue.h (module 'network'): ns3::RedQueue::Stats::unforcedDrop [variable]
+    cls.add_instance_attribute('unforcedDrop', 'uint32_t', is_const=False)
+    return
+
 def register_Ns3SimpleRefCount__Ns3AttributeAccessor_Ns3Empty_Ns3DefaultDeleter__lt__ns3AttributeAccessor__gt___methods(root_module, cls):
     ## simple-ref-count.h (module 'core'): ns3::SimpleRefCount<ns3::AttributeAccessor, ns3::empty, ns3::DefaultDeleter<ns3::AttributeAccessor> >::SimpleRefCount() [constructor]
     cls.add_constructor([])
@@ -5022,6 +5102,47 @@
                    is_pure_virtual=True, is_const=True, is_virtual=True)
     return
 
+def register_Ns3BooleanChecker_methods(root_module, cls):
+    ## boolean.h (module 'core'): ns3::BooleanChecker::BooleanChecker() [constructor]
+    cls.add_constructor([])
+    ## boolean.h (module 'core'): ns3::BooleanChecker::BooleanChecker(ns3::BooleanChecker const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::BooleanChecker const &', 'arg0')])
+    return
+
+def register_Ns3BooleanValue_methods(root_module, cls):
+    cls.add_output_stream_operator()
+    ## boolean.h (module 'core'): ns3::BooleanValue::BooleanValue(ns3::BooleanValue const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::BooleanValue const &', 'arg0')])
+    ## boolean.h (module 'core'): ns3::BooleanValue::BooleanValue() [constructor]
+    cls.add_constructor([])
+    ## boolean.h (module 'core'): ns3::BooleanValue::BooleanValue(bool value) [constructor]
+    cls.add_constructor([param('bool', 'value')])
+    ## boolean.h (module 'core'): ns3::Ptr<ns3::AttributeValue> ns3::BooleanValue::Copy() const [member function]
+    cls.add_method('Copy', 
+                   'ns3::Ptr< ns3::AttributeValue >', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## boolean.h (module 'core'): bool ns3::BooleanValue::DeserializeFromString(std::string value, ns3::Ptr<ns3::AttributeChecker const> checker) [member function]
+    cls.add_method('DeserializeFromString', 
+                   'bool', 
+                   [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], 
+                   is_virtual=True)
+    ## boolean.h (module 'core'): bool ns3::BooleanValue::Get() const [member function]
+    cls.add_method('Get', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## boolean.h (module 'core'): std::string ns3::BooleanValue::SerializeToString(ns3::Ptr<ns3::AttributeChecker const> checker) const [member function]
+    cls.add_method('SerializeToString', 
+                   'std::string', 
+                   [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], 
+                   is_const=True, is_virtual=True)
+    ## boolean.h (module 'core'): void ns3::BooleanValue::Set(bool value) [member function]
+    cls.add_method('Set', 
+                   'void', 
+                   [param('bool', 'value')])
+    return
+
 def register_Ns3CallbackChecker_methods(root_module, cls):
     ## callback.h (module 'core'): ns3::CallbackChecker::CallbackChecker() [constructor]
     cls.add_constructor([])
--- a/src/network/bindings/modulegen__gcc_LP64.py	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/network/bindings/modulegen__gcc_LP64.py	Fri Dec 16 18:51:18 2011 +0100
@@ -222,6 +222,14 @@
     module.add_enum('', ['FRAME_FLAG_NONE', 'FRAME_FLAG_CFP', 'FRAME_FLAG_SHORT_PREAMBLE', 'FRAME_FLAG_WEP', 'FRAME_FLAG_FRAGMENTED', 'FRAME_FLAG_FCS_INCLUDED', 'FRAME_FLAG_DATA_PADDING', 'FRAME_FLAG_BAD_FCS', 'FRAME_FLAG_SHORT_GUARD'], outer_class=root_module['ns3::RadiotapHeader'])
     ## radiotap-header.h (module 'network'): ns3::RadiotapHeader [enumeration]
     module.add_enum('', ['CHANNEL_FLAG_NONE', 'CHANNEL_FLAG_TURBO', 'CHANNEL_FLAG_CCK', 'CHANNEL_FLAG_OFDM', 'CHANNEL_FLAG_SPECTRUM_2GHZ', 'CHANNEL_FLAG_SPECTRUM_5GHZ', 'CHANNEL_FLAG_PASSIVE', 'CHANNEL_FLAG_DYNAMIC', 'CHANNEL_FLAG_GFSK'], outer_class=root_module['ns3::RadiotapHeader'])
+    ## red-queue.h (module 'network'): ns3::RedQueue [class]
+    module.add_class('RedQueue', parent=root_module['ns3::Queue'])
+    ## red-queue.h (module 'network'): ns3::RedQueue [enumeration]
+    module.add_enum('', ['DTYPE_NONE', 'DTYPE_FORCED', 'DTYPE_UNFORCED'], outer_class=root_module['ns3::RedQueue'])
+    ## red-queue.h (module 'network'): ns3::RedQueue::Mode [enumeration]
+    module.add_enum('Mode', ['ILLEGAL', 'PACKETS', 'BYTES'], outer_class=root_module['ns3::RedQueue'])
+    ## red-queue.h (module 'network'): ns3::RedQueue::Stats [struct]
+    module.add_class('Stats', outer_class=root_module['ns3::RedQueue'])
     ## simple-ref-count.h (module 'core'): ns3::SimpleRefCount<ns3::AttributeAccessor, ns3::empty, ns3::DefaultDeleter<ns3::AttributeAccessor> > [class]
     module.add_class('SimpleRefCount', automatic_type_narrowing=True, import_from_module='ns.core', template_parameters=['ns3::AttributeAccessor', 'ns3::empty', 'ns3::DefaultDeleter<ns3::AttributeAccessor>'], parent=root_module['ns3::empty'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
     ## simple-ref-count.h (module 'core'): ns3::SimpleRefCount<ns3::AttributeChecker, ns3::empty, ns3::DefaultDeleter<ns3::AttributeChecker> > [class]
@@ -280,6 +288,10 @@
     module.add_class('AttributeChecker', allow_subclassing=False, automatic_type_narrowing=True, import_from_module='ns.core', parent=root_module['ns3::SimpleRefCount< ns3::AttributeChecker, ns3::empty, ns3::DefaultDeleter<ns3::AttributeChecker> >'])
     ## attribute.h (module 'core'): ns3::AttributeValue [class]
     module.add_class('AttributeValue', allow_subclassing=False, automatic_type_narrowing=True, import_from_module='ns.core', parent=root_module['ns3::SimpleRefCount< ns3::AttributeValue, ns3::empty, ns3::DefaultDeleter<ns3::AttributeValue> >'])
+    ## boolean.h (module 'core'): ns3::BooleanChecker [class]
+    module.add_class('BooleanChecker', import_from_module='ns.core', parent=root_module['ns3::AttributeChecker'])
+    ## boolean.h (module 'core'): ns3::BooleanValue [class]
+    module.add_class('BooleanValue', import_from_module='ns.core', parent=root_module['ns3::AttributeValue'])
     ## callback.h (module 'core'): ns3::CallbackChecker [class]
     module.add_class('CallbackChecker', import_from_module='ns.core', parent=root_module['ns3::AttributeChecker'])
     ## callback.h (module 'core'): ns3::CallbackImplBase [class]
@@ -520,6 +532,8 @@
     register_Ns3PcapFileWrapper_methods(root_module, root_module['ns3::PcapFileWrapper'])
     register_Ns3Queue_methods(root_module, root_module['ns3::Queue'])
     register_Ns3RadiotapHeader_methods(root_module, root_module['ns3::RadiotapHeader'])
+    register_Ns3RedQueue_methods(root_module, root_module['ns3::RedQueue'])
+    register_Ns3RedQueueStats_methods(root_module, root_module['ns3::RedQueue::Stats'])
     register_Ns3SimpleRefCount__Ns3AttributeAccessor_Ns3Empty_Ns3DefaultDeleter__lt__ns3AttributeAccessor__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::AttributeAccessor, ns3::empty, ns3::DefaultDeleter<ns3::AttributeAccessor> >'])
     register_Ns3SimpleRefCount__Ns3AttributeChecker_Ns3Empty_Ns3DefaultDeleter__lt__ns3AttributeChecker__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::AttributeChecker, ns3::empty, ns3::DefaultDeleter<ns3::AttributeChecker> >'])
     register_Ns3SimpleRefCount__Ns3AttributeValue_Ns3Empty_Ns3DefaultDeleter__lt__ns3AttributeValue__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::AttributeValue, ns3::empty, ns3::DefaultDeleter<ns3::AttributeValue> >'])
@@ -545,6 +559,8 @@
     register_Ns3AttributeAccessor_methods(root_module, root_module['ns3::AttributeAccessor'])
     register_Ns3AttributeChecker_methods(root_module, root_module['ns3::AttributeChecker'])
     register_Ns3AttributeValue_methods(root_module, root_module['ns3::AttributeValue'])
+    register_Ns3BooleanChecker_methods(root_module, root_module['ns3::BooleanChecker'])
+    register_Ns3BooleanValue_methods(root_module, root_module['ns3::BooleanValue'])
     register_Ns3CallbackChecker_methods(root_module, root_module['ns3::CallbackChecker'])
     register_Ns3CallbackImplBase_methods(root_module, root_module['ns3::CallbackImplBase'])
     register_Ns3CallbackValue_methods(root_module, root_module['ns3::CallbackValue'])
@@ -4129,6 +4145,70 @@
                    [param('uint64_t', 'tsft')])
     return
 
+def register_Ns3RedQueue_methods(root_module, cls):
+    ## red-queue.h (module 'network'): ns3::RedQueue::RedQueue(ns3::RedQueue const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::RedQueue const &', 'arg0')])
+    ## red-queue.h (module 'network'): ns3::RedQueue::RedQueue() [constructor]
+    cls.add_constructor([])
+    ## red-queue.h (module 'network'): ns3::RedQueue::Mode ns3::RedQueue::GetMode() [member function]
+    cls.add_method('GetMode', 
+                   'ns3::RedQueue::Mode', 
+                   [])
+    ## red-queue.h (module 'network'): uint32_t ns3::RedQueue::GetQueueSize() [member function]
+    cls.add_method('GetQueueSize', 
+                   'uint32_t', 
+                   [])
+    ## red-queue.h (module 'network'): ns3::RedQueue::Stats ns3::RedQueue::GetStats() [member function]
+    cls.add_method('GetStats', 
+                   'ns3::RedQueue::Stats', 
+                   [])
+    ## red-queue.h (module 'network'): static ns3::TypeId ns3::RedQueue::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## red-queue.h (module 'network'): void ns3::RedQueue::SetMode(ns3::RedQueue::Mode mode) [member function]
+    cls.add_method('SetMode', 
+                   'void', 
+                   [param('ns3::RedQueue::Mode', 'mode')])
+    ## red-queue.h (module 'network'): void ns3::RedQueue::SetQueueLimit(uint32_t lim) [member function]
+    cls.add_method('SetQueueLimit', 
+                   'void', 
+                   [param('uint32_t', 'lim')])
+    ## red-queue.h (module 'network'): void ns3::RedQueue::SetTh(double minTh, double maxTh) [member function]
+    cls.add_method('SetTh', 
+                   'void', 
+                   [param('double', 'minTh'), param('double', 'maxTh')])
+    ## red-queue.h (module 'network'): ns3::Ptr<ns3::Packet> ns3::RedQueue::DoDequeue() [member function]
+    cls.add_method('DoDequeue', 
+                   'ns3::Ptr< ns3::Packet >', 
+                   [], 
+                   visibility='private', is_virtual=True)
+    ## red-queue.h (module 'network'): bool ns3::RedQueue::DoEnqueue(ns3::Ptr<ns3::Packet> p) [member function]
+    cls.add_method('DoEnqueue', 
+                   'bool', 
+                   [param('ns3::Ptr< ns3::Packet >', 'p')], 
+                   visibility='private', is_virtual=True)
+    ## red-queue.h (module 'network'): ns3::Ptr<const ns3::Packet> ns3::RedQueue::DoPeek() const [member function]
+    cls.add_method('DoPeek', 
+                   'ns3::Ptr< ns3::Packet const >', 
+                   [], 
+                   is_const=True, visibility='private', is_virtual=True)
+    return
+
+def register_Ns3RedQueueStats_methods(root_module, cls):
+    ## red-queue.h (module 'network'): ns3::RedQueue::Stats::Stats() [constructor]
+    cls.add_constructor([])
+    ## red-queue.h (module 'network'): ns3::RedQueue::Stats::Stats(ns3::RedQueue::Stats const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::RedQueue::Stats const &', 'arg0')])
+    ## red-queue.h (module 'network'): ns3::RedQueue::Stats::forcedDrop [variable]
+    cls.add_instance_attribute('forcedDrop', 'uint32_t', is_const=False)
+    ## red-queue.h (module 'network'): ns3::RedQueue::Stats::qLimDrop [variable]
+    cls.add_instance_attribute('qLimDrop', 'uint32_t', is_const=False)
+    ## red-queue.h (module 'network'): ns3::RedQueue::Stats::unforcedDrop [variable]
+    cls.add_instance_attribute('unforcedDrop', 'uint32_t', is_const=False)
+    return
+
 def register_Ns3SimpleRefCount__Ns3AttributeAccessor_Ns3Empty_Ns3DefaultDeleter__lt__ns3AttributeAccessor__gt___methods(root_module, cls):
     ## simple-ref-count.h (module 'core'): ns3::SimpleRefCount<ns3::AttributeAccessor, ns3::empty, ns3::DefaultDeleter<ns3::AttributeAccessor> >::SimpleRefCount() [constructor]
     cls.add_constructor([])
@@ -5022,6 +5102,47 @@
                    is_pure_virtual=True, is_const=True, is_virtual=True)
     return
 
+def register_Ns3BooleanChecker_methods(root_module, cls):
+    ## boolean.h (module 'core'): ns3::BooleanChecker::BooleanChecker() [constructor]
+    cls.add_constructor([])
+    ## boolean.h (module 'core'): ns3::BooleanChecker::BooleanChecker(ns3::BooleanChecker const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::BooleanChecker const &', 'arg0')])
+    return
+
+def register_Ns3BooleanValue_methods(root_module, cls):
+    cls.add_output_stream_operator()
+    ## boolean.h (module 'core'): ns3::BooleanValue::BooleanValue(ns3::BooleanValue const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::BooleanValue const &', 'arg0')])
+    ## boolean.h (module 'core'): ns3::BooleanValue::BooleanValue() [constructor]
+    cls.add_constructor([])
+    ## boolean.h (module 'core'): ns3::BooleanValue::BooleanValue(bool value) [constructor]
+    cls.add_constructor([param('bool', 'value')])
+    ## boolean.h (module 'core'): ns3::Ptr<ns3::AttributeValue> ns3::BooleanValue::Copy() const [member function]
+    cls.add_method('Copy', 
+                   'ns3::Ptr< ns3::AttributeValue >', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## boolean.h (module 'core'): bool ns3::BooleanValue::DeserializeFromString(std::string value, ns3::Ptr<ns3::AttributeChecker const> checker) [member function]
+    cls.add_method('DeserializeFromString', 
+                   'bool', 
+                   [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], 
+                   is_virtual=True)
+    ## boolean.h (module 'core'): bool ns3::BooleanValue::Get() const [member function]
+    cls.add_method('Get', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## boolean.h (module 'core'): std::string ns3::BooleanValue::SerializeToString(ns3::Ptr<ns3::AttributeChecker const> checker) const [member function]
+    cls.add_method('SerializeToString', 
+                   'std::string', 
+                   [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], 
+                   is_const=True, is_virtual=True)
+    ## boolean.h (module 'core'): void ns3::BooleanValue::Set(bool value) [member function]
+    cls.add_method('Set', 
+                   'void', 
+                   [param('bool', 'value')])
+    return
+
 def register_Ns3CallbackChecker_methods(root_module, cls):
     ## callback.h (module 'core'): ns3::CallbackChecker::CallbackChecker() [constructor]
     cls.add_constructor([])
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/network/examples/droptail_vs_red.cc	Fri Dec 16 18:51:18 2011 +0100
@@ -0,0 +1,164 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: John Abraham <john.abraham@gatech.edu> 
+ *
+ */
+
+
+#include "ns3/core-module.h"
+#include "ns3/network-module.h"
+#include "ns3/internet-module.h"
+#include "ns3/point-to-point-module.h"
+#include "ns3/applications-module.h"
+#include "ns3/point-to-point-layout-module.h"
+
+#include <iostream>
+#include <iomanip>
+#include <map>
+
+using namespace ns3;
+using namespace std;
+
+
+int main (int argc, char *argv[])
+{
+  uint32_t    nLeaf = 5; 
+  uint32_t    maxPackets = 100;
+  uint32_t    modeBytes  = 0;
+  double      minTh = 50;
+  double      maxTh = 80;
+  uint32_t    pktSize = 512;
+  std::string appDataRate = "10Mbps";
+  std::string queueType = "DropTail";
+  uint16_t port = 5001;
+  std::string bottleNeckLinkBw = "1Mbps";
+  std::string bottleNeckLinkDelay = "50ms";
+
+  CommandLine cmd;
+  cmd.AddValue ("nLeaf",     "Number of left and right side leaf nodes", nLeaf);
+  cmd.AddValue ("maxPackets","Max Packets allowed in the queue", maxPackets);
+  cmd.AddValue ("queueType", "Set Queue type to DropTail or RED", queueType);
+  cmd.AddValue ("appPktSize", "Set OnOff App Packet Size", pktSize);
+  cmd.AddValue ("appDataRate", "Set OnOff App DataRate", appDataRate);
+  cmd.AddValue ("modeBytes", "Set Queue mode to Packets <0> or bytes <1>", modeBytes);
+
+  cmd.AddValue ("redMinTh", "RED queue minimum threshold", minTh);
+  cmd.AddValue ("redMaxTh", "RED queue maximum threshold", maxTh);
+  cmd.Parse (argc,argv);
+
+  if ((queueType != "RED") && (queueType != "DropTail"))
+    {
+      NS_ABORT_MSG ("Invalid queue type: Use --queueType=RED or --queueType=DropTail");
+    }
+
+  Config::SetDefault ("ns3::OnOffApplication::PacketSize", UintegerValue (pktSize));
+  Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue (appDataRate));
+
+
+  if (!modeBytes)
+    {
+      Config::SetDefault ("ns3::DropTailQueue::Mode", StringValue ("Packets"));
+      Config::SetDefault ("ns3::DropTailQueue::MaxPackets", UintegerValue (maxPackets));
+      Config::SetDefault ("ns3::RedQueue::Mode", StringValue ("Packets"));
+      Config::SetDefault ("ns3::RedQueue::QueueLimit", UintegerValue (maxPackets));
+    }
+  else 
+    {
+      Config::SetDefault ("ns3::DropTailQueue::Mode", StringValue ("Bytes"));
+      Config::SetDefault ("ns3::DropTailQueue::MaxBytes", UintegerValue (maxPackets * pktSize));
+      Config::SetDefault ("ns3::RedQueue::Mode", StringValue ("Bytes"));
+      Config::SetDefault ("ns3::RedQueue::QueueLimit", UintegerValue (maxPackets * pktSize));
+      minTh *= pktSize; 
+      maxTh *= pktSize;
+    }
+
+  // Create the point-to-point link helpers
+  PointToPointHelper bottleNeckLink;
+  bottleNeckLink.SetDeviceAttribute  ("DataRate", StringValue (bottleNeckLinkBw));
+  bottleNeckLink.SetChannelAttribute ("Delay", StringValue (bottleNeckLinkDelay));
+  if (queueType == "RED")
+    {
+      bottleNeckLink.SetQueue ("ns3::RedQueue",
+                               "MinTh", DoubleValue (minTh),
+                               "MaxTh", DoubleValue (maxTh),
+                               "LinkBandwidth", StringValue (bottleNeckLinkBw),
+                               "LinkDelay", StringValue (bottleNeckLinkDelay));
+    }
+  PointToPointHelper pointToPointLeaf;
+  pointToPointLeaf.SetDeviceAttribute    ("DataRate", StringValue ("10Mbps"));
+  pointToPointLeaf.SetChannelAttribute   ("Delay", StringValue ("1ms"));
+
+  PointToPointDumbbellHelper d (nLeaf, pointToPointLeaf,
+                                nLeaf, pointToPointLeaf,
+                                bottleNeckLink);
+
+  // Install Stack
+  InternetStackHelper stack;
+  d.InstallStack (stack);
+
+  // Assign IP Addresses
+  d.AssignIpv4Addresses (Ipv4AddressHelper ("10.1.1.0", "255.255.255.0"),
+                         Ipv4AddressHelper ("10.2.1.0", "255.255.255.0"),
+                         Ipv4AddressHelper ("10.3.1.0", "255.255.255.0"));
+
+  // Install on/off app on all right side nodes
+  OnOffHelper clientHelper ("ns3::TcpSocketFactory", Address ());
+  clientHelper.SetAttribute ("OnTime", RandomVariableValue (UniformVariable (0, 1)));
+  clientHelper.SetAttribute ("OffTime", RandomVariableValue (UniformVariable (0, 1)));
+  Address sinkLocalAddress (InetSocketAddress (Ipv4Address::GetAny (), port));
+  PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory", sinkLocalAddress);
+  ApplicationContainer sinkApps; 
+  for (uint32_t i = 0; i < d.LeftCount (); ++i)
+    {
+      sinkApps.Add (packetSinkHelper.Install (d.GetLeft (i)));
+    }
+  sinkApps.Start (Seconds (0.0));
+  sinkApps.Stop (Seconds (30.0));
+
+  ApplicationContainer clientApps;
+  for (uint32_t i = 0; i < d.RightCount (); ++i)
+    {
+      // Create an on/off app sending packets to the left side
+      AddressValue remoteAddress (InetSocketAddress (d.GetLeftIpv4Address (i), port));
+      clientHelper.SetAttribute ("Remote", remoteAddress);
+      clientApps.Add (clientHelper.Install (d.GetRight (i)));
+    }
+  clientApps.Start (Seconds (1.0)); // Start 1 second after sink
+  clientApps.Stop (Seconds (15.0)); // Stop before the sink
+
+  Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
+
+  std::cout << "Running the simulation" << std::endl;
+  Simulator::Run ();
+
+  uint32_t totalRxBytesCounter = 0;
+  for (uint32_t i = 0; i < sinkApps.GetN (); i++)
+    {
+      Ptr <Application> app = sinkApps.Get (i);
+      Ptr <PacketSink> pktSink = DynamicCast <PacketSink> (app);
+      totalRxBytesCounter += pktSink->GetTotalRx ();
+    }
+  NS_LOG_UNCOND ("----------------------------\nQueue Type:" 
+                 << queueType 
+                 << "\nGoodput Bytes/sec:" 
+                 << totalRxBytesCounter/Simulator::Now ().GetSeconds ()); 
+  NS_LOG_UNCOND ("----------------------------");
+
+
+  std::cout << "Destroying the simulation" << std::endl;
+  Simulator::Destroy ();
+  return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/network/examples/red-tests.cc	Fri Dec 16 18:51:18 2011 +0100
@@ -0,0 +1,482 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Authors: Marcos Talau <talau@users.sourceforge.net>
+ *          Duy Nguyen <duy@soe.ucsc.edu>
+ *
+ */
+
+/**
+ * These validation tests are detailed in http://icir.org/floyd/papers/redsims.ps
+ *
+ * In this code the tests 1, 3, 4 and 5 refer to the tests corresponding to
+ * Figure 1, 3, 4, and 5 respectively from the document mentioned above.
+ */
+
+/** Network topology
+ *
+ *    10Mb/s, 2ms                            10Mb/s, 4ms
+ * n0--------------|                    |---------------n4
+ *                 |   1.5Mbps/s, 20ms  |
+ *                 n2------------------n3
+ *    10Mb/s, 3ms  |                    |    10Mb/s, 5ms
+ * n1--------------|                    |---------------n5
+ *
+ *
+ */
+
+#include "ns3/core-module.h"
+#include "ns3/network-module.h"
+#include "ns3/internet-module.h"
+#include "ns3/flow-monitor-helper.h"
+#include "ns3/point-to-point-module.h"
+#include "ns3/applications-module.h"
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("RedTests");
+
+uint32_t checkTimes;
+double avgQueueSize;
+
+// The times
+double global_start_time;
+double global_stop_time;
+double sink_start_time;
+double sink_stop_time;
+double client_start_time;
+double client_stop_time;
+
+NodeContainer n0n2;
+NodeContainer n1n2;
+NodeContainer n2n3;
+NodeContainer n3n4;
+NodeContainer n3n5;
+
+Ipv4InterfaceContainer i0i2;
+Ipv4InterfaceContainer i1i2;
+Ipv4InterfaceContainer i2i3;
+Ipv4InterfaceContainer i3i4;
+Ipv4InterfaceContainer i3i5;
+
+std::stringstream filePlotQueue;
+std::stringstream filePlotQueueAvg;
+
+void
+CheckQueueSize (Ptr<Queue> queue)
+{
+  uint32_t qSize = StaticCast<RedQueue> (queue)->GetQueueSize ();
+
+  avgQueueSize += qSize;
+  checkTimes++;
+
+  // check queue size every 1/100 of a second
+  Simulator::Schedule (Seconds (0.01), &CheckQueueSize, queue);
+
+  std::ofstream fPlotQueue (filePlotQueue.str ().c_str (), std::ios::out|std::ios::app);
+  fPlotQueue << Simulator::Now ().GetSeconds () << " " << qSize << std::endl;
+  fPlotQueue.close ();
+
+  std::ofstream fPlotQueueAvg (filePlotQueueAvg.str ().c_str (), std::ios::out|std::ios::app);
+  fPlotQueueAvg << Simulator::Now ().GetSeconds () << " " << avgQueueSize / checkTimes << std::endl;
+  fPlotQueueAvg.close ();
+}
+
+void
+BuildAppsTest (uint32_t test)
+{
+  if ( (test == 1) || (test == 3) )
+    {
+      // SINK is in the right side
+      uint16_t port = 50000;
+      Address sinkLocalAddress (InetSocketAddress (Ipv4Address::GetAny (), port));
+      PacketSinkHelper sinkHelper ("ns3::TcpSocketFactory", sinkLocalAddress);
+      ApplicationContainer sinkApp = sinkHelper.Install (n3n4.Get (1));
+      sinkApp.Start (Seconds (sink_start_time));
+      sinkApp.Stop (Seconds (sink_stop_time));
+
+      // Connection one
+      // Clients are in left side
+      /*
+       * Create the OnOff applications to send TCP to the server
+       * onoffhelper is a client that send data to TCP destination
+       */
+      OnOffHelper clientHelper1 ("ns3::TcpSocketFactory", Address ());
+      clientHelper1.SetAttribute 
+        ("OnTime", RandomVariableValue (ConstantVariable (1)));
+      clientHelper1.SetAttribute 
+        ("OffTime", RandomVariableValue (ConstantVariable (0)));
+      clientHelper1.SetAttribute 
+        ("DataRate", DataRateValue (DataRate ("10Mb/s")));
+      clientHelper1.SetAttribute 
+        ("PacketSize", UintegerValue (1000));
+
+      ApplicationContainer clientApps1;
+      AddressValue remoteAddress
+        (InetSocketAddress (i3i4.GetAddress (1), port));
+      clientHelper1.SetAttribute ("Remote", remoteAddress);
+      clientApps1.Add (clientHelper1.Install (n0n2.Get (0)));
+      clientApps1.Start (Seconds (client_start_time));
+      clientApps1.Stop (Seconds (client_stop_time));
+
+      // Connection two
+      OnOffHelper clientHelper2 ("ns3::TcpSocketFactory", Address ());
+      clientHelper2.SetAttribute 
+        ("OnTime", RandomVariableValue (ConstantVariable (1)));
+      clientHelper2.SetAttribute 
+        ("OffTime", RandomVariableValue (ConstantVariable (0)));
+      clientHelper2.SetAttribute 
+        ("DataRate", DataRateValue (DataRate ("10Mb/s")));
+      clientHelper2.SetAttribute 
+        ("PacketSize", UintegerValue (1000));
+
+      ApplicationContainer clientApps2;
+      clientHelper2.SetAttribute ("Remote", remoteAddress);
+      clientApps2.Add (clientHelper2.Install (n1n2.Get (0)));
+      clientApps2.Start (Seconds (3.0));
+      clientApps2.Stop (Seconds (client_stop_time));
+    }
+  else // 4 or 5
+    {
+      // SINKs
+      // #1
+      uint16_t port1 = 50001;
+      Address sinkLocalAddress1 (InetSocketAddress (Ipv4Address::GetAny (), port1));
+      PacketSinkHelper sinkHelper1 ("ns3::TcpSocketFactory", sinkLocalAddress1);
+      ApplicationContainer sinkApp1 = sinkHelper1.Install (n3n4.Get (1));
+      sinkApp1.Start (Seconds (sink_start_time));
+      sinkApp1.Stop (Seconds (sink_stop_time));
+      // #2
+      uint16_t port2 = 50002;
+      Address sinkLocalAddress2 (InetSocketAddress (Ipv4Address::GetAny (), port2));
+      PacketSinkHelper sinkHelper2 ("ns3::TcpSocketFactory", sinkLocalAddress2);
+      ApplicationContainer sinkApp2 = sinkHelper2.Install (n3n5.Get (1));
+      sinkApp2.Start (Seconds (sink_start_time));
+      sinkApp2.Stop (Seconds (sink_stop_time));
+      // #3
+      uint16_t port3 = 50003;
+      Address sinkLocalAddress3 (InetSocketAddress (Ipv4Address::GetAny (), port3));
+      PacketSinkHelper sinkHelper3 ("ns3::TcpSocketFactory", sinkLocalAddress3);
+      ApplicationContainer sinkApp3 = sinkHelper3.Install (n0n2.Get (0));
+      sinkApp3.Start (Seconds (sink_start_time));
+      sinkApp3.Stop (Seconds (sink_stop_time));
+      // #4
+      uint16_t port4 = 50004;
+      Address sinkLocalAddress4 (InetSocketAddress (Ipv4Address::GetAny (), port4));
+      PacketSinkHelper sinkHelper4 ("ns3::TcpSocketFactory", sinkLocalAddress4);
+      ApplicationContainer sinkApp4 = sinkHelper4.Install (n1n2.Get (0));
+      sinkApp4.Start (Seconds (sink_start_time));
+      sinkApp4.Stop (Seconds (sink_stop_time));
+
+      // Connection #1
+      /*
+       * Create the OnOff applications to send TCP to the server
+       * onoffhelper is a client that send data to TCP destination
+       */
+      OnOffHelper clientHelper1 ("ns3::TcpSocketFactory", Address ());
+      clientHelper1.SetAttribute 
+        ("OnTime", RandomVariableValue (ConstantVariable (1)));
+      clientHelper1.SetAttribute 
+        ("OffTime", RandomVariableValue (ConstantVariable (0)));
+      clientHelper1.SetAttribute 
+        ("DataRate", DataRateValue (DataRate ("10Mb/s")));
+      clientHelper1.SetAttribute 
+        ("PacketSize", UintegerValue (1000));
+
+      ApplicationContainer clientApps1;
+      AddressValue remoteAddress1
+        (InetSocketAddress (i3i4.GetAddress (1), port1));
+      clientHelper1.SetAttribute ("Remote", remoteAddress1);
+      clientApps1.Add (clientHelper1.Install (n0n2.Get (0)));
+      clientApps1.Start (Seconds (client_start_time));
+      clientApps1.Stop (Seconds (client_stop_time));
+
+      // Connection #2
+      OnOffHelper clientHelper2 ("ns3::TcpSocketFactory", Address ());
+      clientHelper2.SetAttribute 
+        ("OnTime", RandomVariableValue (ConstantVariable (1)));
+      clientHelper2.SetAttribute 
+        ("OffTime", RandomVariableValue (ConstantVariable (0)));
+      clientHelper2.SetAttribute 
+        ("DataRate", DataRateValue (DataRate ("10Mb/s")));
+      clientHelper2.SetAttribute 
+        ("PacketSize", UintegerValue (1000));
+
+      ApplicationContainer clientApps2;
+      AddressValue remoteAddress2
+        (InetSocketAddress (i3i5.GetAddress (1), port2));
+      clientHelper2.SetAttribute ("Remote", remoteAddress2);
+      clientApps2.Add (clientHelper2.Install (n1n2.Get (0)));
+      clientApps2.Start (Seconds (2.0));
+      clientApps2.Stop (Seconds (client_stop_time));
+
+      // Connection #3
+      OnOffHelper clientHelper3 ("ns3::TcpSocketFactory", Address ());
+      clientHelper3.SetAttribute 
+        ("OnTime", RandomVariableValue (ConstantVariable (1)));
+      clientHelper3.SetAttribute 
+        ("OffTime", RandomVariableValue (ConstantVariable (0)));
+      clientHelper3.SetAttribute 
+        ("DataRate", DataRateValue (DataRate ("10Mb/s")));
+      clientHelper3.SetAttribute 
+        ("PacketSize", UintegerValue (1000));
+
+      ApplicationContainer clientApps3;
+      AddressValue remoteAddress3
+        (InetSocketAddress (i0i2.GetAddress (0), port3));
+      clientHelper3.SetAttribute ("Remote", remoteAddress3);
+      clientApps3.Add (clientHelper3.Install (n3n4.Get (1)));
+      clientApps3.Start (Seconds (3.5));
+      clientApps3.Stop (Seconds (client_stop_time));
+
+      // Connection #4
+      OnOffHelper clientHelper4 ("ns3::TcpSocketFactory", Address ());
+      clientHelper4.SetAttribute 
+        ("OnTime", RandomVariableValue (ConstantVariable (1)));
+      clientHelper4.SetAttribute 
+        ("OffTime", RandomVariableValue (ConstantVariable (0)));
+      clientHelper4.SetAttribute 
+        ("DataRate", DataRateValue (DataRate ("40b/s")));
+      clientHelper4.SetAttribute 
+        ("PacketSize", UintegerValue (5 * 8)); // telnet
+
+      ApplicationContainer clientApps4;
+      AddressValue remoteAddress4
+        (InetSocketAddress (i1i2.GetAddress (0), port4));
+      clientHelper4.SetAttribute ("Remote", remoteAddress4);
+      clientApps4.Add (clientHelper4.Install (n3n5.Get (1)));
+      clientApps4.Start (Seconds (1.0));
+      clientApps4.Stop (Seconds (client_stop_time));
+    }
+}
+
+int
+main (int argc, char *argv[])
+{
+  // LogComponentEnable ("RedExamples", LOG_LEVEL_INFO);
+  // LogComponentEnable ("TcpNewReno", LOG_LEVEL_INFO);
+  // LogComponentEnable ("RedQueue", LOG_LEVEL_FUNCTION);
+  LogComponentEnable ("RedQueue", LOG_LEVEL_INFO);
+
+  uint32_t redTest;
+  std::string redLinkDataRate = "1.5Mbps";
+  std::string redLinkDelay = "20ms";
+
+  std::string pathOut;
+  bool writeForPlot = false;
+  bool writePcap = false;
+  bool flowMonitor = false;
+
+  bool printRedStats = true;
+
+  global_start_time = 0.0;
+  global_stop_time = 11; 
+  sink_start_time = global_start_time;
+  sink_stop_time = global_stop_time + 3.0;
+  client_start_time = sink_start_time + 0.2;
+  client_stop_time = global_stop_time - 2.0;
+
+  // Configuration and command line parameter parsing
+  redTest = 1;
+  // Will only save in the directory if enable opts below
+  pathOut = "."; // Current directory
+  CommandLine cmd;
+  cmd.AddValue ("testNumber", "Run test 1, 3, 4 or 5", redTest);
+  cmd.AddValue ("pathOut", "Path to save results from --writeForPlot/--writePcap/--writeFlowMonitor", pathOut);
+  cmd.AddValue ("writeForPlot", "<0/1> to write results for plot (gnuplot)", writeForPlot);
+  cmd.AddValue ("writePcap", "<0/1> to write results in pcapfile", writePcap);
+  cmd.AddValue ("writeFlowMonitor", "<0/1> to enable Flow Monitor and write their results", flowMonitor);
+
+  cmd.Parse (argc, argv);
+  if ( (redTest != 1) && (redTest != 3) && (redTest != 4) && (redTest != 5) )
+    {
+      NS_ABORT_MSG ("Invalid test number. Supported tests are 1, 3, 4 or 5");
+    }
+
+  NS_LOG_INFO ("Create nodes");
+  NodeContainer c;
+  c.Create (6);
+  Names::Add ( "N0", c.Get (0));
+  Names::Add ( "N1", c.Get (1));
+  Names::Add ( "N2", c.Get (2));
+  Names::Add ( "N3", c.Get (3));
+  Names::Add ( "N4", c.Get (4));
+  Names::Add ( "N5", c.Get (5));
+  n0n2 = NodeContainer (c.Get (0), c.Get (2));
+  n1n2 = NodeContainer (c.Get (1), c.Get (2));
+  n2n3 = NodeContainer (c.Get (2), c.Get (3));
+  n3n4 = NodeContainer (c.Get (3), c.Get (4));
+  n3n5 = NodeContainer (c.Get (3), c.Get (5));
+
+  Config::SetDefault ("ns3::TcpL4Protocol::SocketType", StringValue ("ns3::TcpReno"));
+  // 42 = headers size
+  Config::SetDefault ("ns3::TcpSocket::SegmentSize", UintegerValue (1000 - 42));
+  Config::SetDefault ("ns3::TcpSocket::DelAckCount", UintegerValue (1));
+  GlobalValue::Bind ("ChecksumEnabled", BooleanValue (false));
+
+  uint32_t meanPktSize = 500;
+
+  // RED params
+  NS_LOG_INFO ("Set RED params");
+  Config::SetDefault ("ns3::RedQueue::Mode", StringValue ("Packets"));
+  Config::SetDefault ("ns3::RedQueue::MeanPktSize", UintegerValue (meanPktSize));
+  Config::SetDefault ("ns3::RedQueue::Wait", BooleanValue (true));
+  Config::SetDefault ("ns3::RedQueue::Gentle", BooleanValue (true));
+  Config::SetDefault ("ns3::RedQueue::QW", DoubleValue (0.002));
+  Config::SetDefault ("ns3::RedQueue::MinTh", DoubleValue (5));
+  Config::SetDefault ("ns3::RedQueue::MaxTh", DoubleValue (15));
+  Config::SetDefault ("ns3::RedQueue::QueueLimit", UintegerValue (25));
+
+  if (redTest == 3) // test like 1, but with bad params
+    {
+      Config::SetDefault ("ns3::RedQueue::MaxTh", DoubleValue (10));
+      Config::SetDefault ("ns3::RedQueue::QW", DoubleValue (0.003));
+    }
+  else if (redTest == 5) // test 5, same of test 4, but in byte mode
+    {
+      Config::SetDefault ("ns3::RedQueue::Mode", StringValue ("Bytes"));
+      Config::SetDefault ("ns3::RedQueue::Ns1Compat", BooleanValue (true));
+      Config::SetDefault ("ns3::RedQueue::MinTh", DoubleValue (5 * meanPktSize));
+      Config::SetDefault ("ns3::RedQueue::MaxTh", DoubleValue (15 * meanPktSize));
+      Config::SetDefault ("ns3::RedQueue::QueueLimit", UintegerValue (25 * meanPktSize));
+    }
+
+  NS_LOG_INFO ("Install internet stack on all nodes.");
+  InternetStackHelper internet;
+  internet.Install (c);
+
+  NS_LOG_INFO ("Create channels");
+  PointToPointHelper p2p;
+
+  p2p.SetQueue ("ns3::DropTailQueue");
+  p2p.SetDeviceAttribute ("DataRate", StringValue ("10Mbps"));
+  p2p.SetChannelAttribute ("Delay", StringValue ("2ms"));
+  NetDeviceContainer devn0n2 = p2p.Install (n0n2);
+
+  p2p.SetQueue ("ns3::DropTailQueue");
+  p2p.SetDeviceAttribute ("DataRate", StringValue ("10Mbps"));
+  p2p.SetChannelAttribute ("Delay", StringValue ("3ms"));
+  NetDeviceContainer devn1n2 = p2p.Install (n1n2);
+
+  p2p.SetQueue ("ns3::RedQueue", // only backbone link has RED queue
+                "LinkBandwidth", StringValue (redLinkDataRate),
+                "LinkDelay", StringValue (redLinkDelay)); 
+  p2p.SetDeviceAttribute ("DataRate", StringValue (redLinkDataRate));
+  p2p.SetChannelAttribute ("Delay", StringValue (redLinkDelay));
+  NetDeviceContainer devn2n3 = p2p.Install (n2n3);
+
+  p2p.SetQueue ("ns3::DropTailQueue");
+  p2p.SetDeviceAttribute ("DataRate", StringValue ("10Mbps"));
+  p2p.SetChannelAttribute ("Delay", StringValue ("4ms"));
+  NetDeviceContainer devn3n4 = p2p.Install (n3n4);
+
+  p2p.SetQueue ("ns3::DropTailQueue");
+  p2p.SetDeviceAttribute ("DataRate", StringValue ("10Mbps"));
+  p2p.SetChannelAttribute ("Delay", StringValue ("5ms"));
+  NetDeviceContainer devn3n5 = p2p.Install (n3n5);
+
+  NS_LOG_INFO ("Assign IP Addresses");
+  Ipv4AddressHelper ipv4;
+
+  ipv4.SetBase ("10.1.1.0", "255.255.255.0");
+  i0i2 = ipv4.Assign (devn0n2);
+
+  ipv4.SetBase ("10.1.2.0", "255.255.255.0");
+  i1i2 = ipv4.Assign (devn1n2);
+
+  ipv4.SetBase ("10.1.3.0", "255.255.255.0");
+  i2i3 = ipv4.Assign (devn2n3);
+
+  ipv4.SetBase ("10.1.4.0", "255.255.255.0");
+  i3i4 = ipv4.Assign (devn3n4);
+
+  ipv4.SetBase ("10.1.5.0", "255.255.255.0");
+  i3i5 = ipv4.Assign (devn3n5);
+
+  // Set up the routing
+  Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
+
+  if (redTest == 5) 
+    {
+      // like in ns2 test, r2 -> r1, have a queue in packet mode
+      Ptr<PointToPointNetDevice> nd = StaticCast<PointToPointNetDevice> (devn2n3.Get (1));
+      Ptr<Queue> queue = nd->GetQueue ();
+
+      StaticCast<RedQueue> (queue)->SetMode (RedQueue::PACKETS);
+      StaticCast<RedQueue> (queue)->SetTh (5, 15);
+      StaticCast<RedQueue> (queue)->SetQueueLimit (25);
+    }
+
+  BuildAppsTest (redTest);
+
+  if (writePcap)
+    {
+      PointToPointHelper ptp;
+      std::stringstream stmp;
+      stmp << pathOut << "/red";
+      ptp.EnablePcapAll (stmp.str ().c_str ());
+    }
+
+  Ptr<FlowMonitor> flowmon;
+  if (flowMonitor)
+    {
+      FlowMonitorHelper flowmonHelper;
+      flowmon = flowmonHelper.InstallAll ();
+    }
+
+  if (writeForPlot)
+    {
+      filePlotQueue << pathOut << "/" << "red-queue.plotme";
+      filePlotQueueAvg << pathOut << "/" << "red-queue_avg.plotme";
+
+      remove (filePlotQueue.str ().c_str ());
+      remove (filePlotQueueAvg.str ().c_str ());
+      Ptr<PointToPointNetDevice> nd = StaticCast<PointToPointNetDevice> (devn2n3.Get (0));
+      Ptr<Queue> queue = nd->GetQueue ();
+      Simulator::ScheduleNow (&CheckQueueSize, queue);
+    }
+
+  Simulator::Stop (Seconds (sink_stop_time));
+  Simulator::Run ();
+
+  if (flowMonitor)
+    {
+      std::stringstream stmp;
+      stmp << pathOut << "/red.flowmon";
+
+      flowmon->SerializeToXmlFile (stmp.str ().c_str (), false, false);
+    }
+
+  if (printRedStats)
+    {
+      Ptr<PointToPointNetDevice> nd = StaticCast<PointToPointNetDevice> (devn2n3.Get (0));
+      RedQueue::Stats st = StaticCast<RedQueue> (nd->GetQueue ())->GetStats ();
+      std::cout << "*** RED stats from Node 2 queue ***" << std::endl;
+      std::cout << "\t " << st.unforcedDrop << " drops due prob mark" << std::endl;
+      std::cout << "\t " << st.forcedDrop << " drops due hard mark" << std::endl;
+      std::cout << "\t " << st.qLimDrop << " drops due queue full" << std::endl;
+
+      nd = StaticCast<PointToPointNetDevice> (devn2n3.Get (1));
+      st = StaticCast<RedQueue> (nd->GetQueue ())->GetStats ();
+      std::cout << "*** RED stats from Node 3 queue ***" << std::endl;
+      std::cout << "\t " << st.unforcedDrop << " drops due prob mark" << std::endl;
+      std::cout << "\t " << st.forcedDrop << " drops due hard mark" << std::endl;
+      std::cout << "\t " << st.qLimDrop << " drops due queue full" << std::endl;
+    }
+
+  Simulator::Destroy ();
+
+  return 0;
+}
--- a/src/network/examples/wscript	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/network/examples/wscript	Fri Dec 16 18:51:18 2011 +0100
@@ -10,3 +10,8 @@
     obj = bld.create_ns3_program('main-packet-tag', ['network'])
     obj.source = 'main-packet-tag.cc'
 
+    obj = bld.create_ns3_program('red-tests', ['point-to-point', 'internet', 'applications', 'flow-monitor'])
+    obj.source = 'red-tests.cc'
+
+    obj = bld.create_ns3_program('droptail_vs_red', ['point-to-point', 'point-to-point-layout', 'internet', 'applications'])
+    obj.source = 'droptail_vs_red.cc'
--- a/src/network/model/packet.h	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/network/model/packet.h	Fri Dec 16 18:51:18 2011 +0100
@@ -168,9 +168,10 @@
  * were serialized in the byte buffer. The maintenance of metadata is
  * optional and disabled by default. To enable it, you must call
  * Packet::EnablePrinting and this will allow you to get non-empty
- * output from Packet::Print and Packet::Print. If you wish to only enable
+ * output from Packet::Print. If you wish to only enable
  * checking of metadata, and do not need any printing capability, you can
- * call Packet::EnableChecking: its runtime cost is lower than Packet::EnablePrinting.
+ * call Packet::EnableChecking: its runtime cost is lower than
+ * Packet::EnablePrinting.
  *
  * - The set of tags contain simulation-specific information which cannot
  * be stored in the packet byte buffer because the protocol headers or trailers
@@ -415,7 +416,7 @@
   /**
    * By default, packets do not keep around enough metadata to
    * perform the operations requested by the Print methods. If you
-   * want to be able to invoke any of the two ::Print methods, 
+   * want to be able the Packet::Print method, 
    * you need to invoke this method at least once during the 
    * simulation setup and before any packet is created.
    */
--- a/src/network/test/examples-to-run.py	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/network/test/examples-to-run.py	Fri Dec 16 18:51:18 2011 +0100
@@ -10,6 +10,7 @@
 cpp_examples = [
     ("main-packet-header", "True", "True"),
     ("main-packet-tag", "True", "True"),
+    ("red-tests", "True", "True"),
 ]
 
 # A list of Python examples to run in order to ensure that they remain
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/network/test/red-queue-test-suite.cc	Fri Dec 16 18:51:18 2011 +0100
@@ -0,0 +1,283 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright © 2011 Marcos Talau
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Marcos Talau (talau@users.sourceforge.net)
+ *
+ */
+
+#include "ns3/test.h"
+#include "ns3/red-queue.h"
+#include "ns3/uinteger.h"
+#include "ns3/string.h"
+#include "ns3/double.h"
+#include "ns3/log.h"
+#include "ns3/simulator.h"
+
+namespace ns3 {
+
+class RedQueueTestCase : public TestCase
+{
+public:
+  RedQueueTestCase ();
+  virtual void DoRun (void);
+private:
+  void Enqueue (Ptr<RedQueue> queue, uint32_t size, uint32_t nPkt);
+  void RunRedTest (StringValue mode);
+};
+
+RedQueueTestCase::RedQueueTestCase ()
+  : TestCase ("Sanity check on the red queue implementation")
+{
+}
+
+void
+RedQueueTestCase::RunRedTest (StringValue mode)
+{
+  uint32_t pktSize = 0;
+  // 1 for packets; pktSize for bytes
+  uint32_t modeSize = 1;
+  double minTh = 2;
+  double maxTh = 5;
+  uint32_t qSize = 8;
+  Ptr<RedQueue> queue = CreateObject<RedQueue> ();
+
+  // test 1: simple enqueue/dequeue with no drops
+  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", mode), true,
+                         "Verify that we can actually set the attribute Mode");
+  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
+                         "Verify that we can actually set the attribute MinTh");
+  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
+                         "Verify that we can actually set the attribute MaxTh");
+  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueLimit", UintegerValue (qSize)), true,
+                         "Verify that we can actually set the attribute QueueLimit");
+  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.002)), true,
+                         "Verify that we can actually set the attribute QW");
+
+  if (queue->GetMode () == RedQueue::BYTES)
+    {
+      pktSize = 1000;
+      modeSize = pktSize;
+      queue->SetTh (minTh * pktSize, maxTh * pktSize);
+      queue->SetQueueLimit (qSize * pktSize);
+    }
+
+  Ptr<Packet> p1, p2, p3, p4, p5, p6, p7, p8;
+  p1 = Create<Packet> (pktSize);
+  p2 = Create<Packet> (pktSize);
+  p3 = Create<Packet> (pktSize);
+  p4 = Create<Packet> (pktSize);
+  p5 = Create<Packet> (pktSize);
+  p6 = Create<Packet> (pktSize);
+  p7 = Create<Packet> (pktSize);
+  p8 = Create<Packet> (pktSize);
+
+  NS_TEST_EXPECT_MSG_EQ (queue->GetQueueSize (), 0 * modeSize, "There should be no packets in there");
+  queue->Enqueue (p1);
+  NS_TEST_EXPECT_MSG_EQ (queue->GetQueueSize (), 1 * modeSize, "There should be one packet in there");
+  queue->Enqueue (p2);
+  NS_TEST_EXPECT_MSG_EQ (queue->GetQueueSize (), 2 * modeSize, "There should be two packets in there");
+  queue->Enqueue (p3);
+  queue->Enqueue (p4);
+  queue->Enqueue (p5);
+  queue->Enqueue (p6);
+  queue->Enqueue (p7);
+  queue->Enqueue (p8);
+  NS_TEST_EXPECT_MSG_EQ (queue->GetQueueSize (), 8 * modeSize, "There should be eight packets in there");
+
+  Ptr<Packet> p;
+
+  p = queue->Dequeue ();
+  NS_TEST_EXPECT_MSG_EQ ((p != 0), true, "I want to remove the first packet");
+  NS_TEST_EXPECT_MSG_EQ (queue->GetQueueSize (), 7 * modeSize, "There should be seven packets in there");
+  NS_TEST_EXPECT_MSG_EQ (p->GetUid (), p1->GetUid (), "was this the first packet ?");
+
+  p = queue->Dequeue ();
+  NS_TEST_EXPECT_MSG_EQ ((p != 0), true, "I want to remove the second packet");
+  NS_TEST_EXPECT_MSG_EQ (queue->GetQueueSize (), 6 * modeSize, "There should be six packet in there");
+  NS_TEST_EXPECT_MSG_EQ (p->GetUid (), p2->GetUid (), "Was this the second packet ?");
+
+  p = queue->Dequeue ();
+  NS_TEST_EXPECT_MSG_EQ ((p != 0), true, "I want to remove the third packet");
+  NS_TEST_EXPECT_MSG_EQ (queue->GetQueueSize (), 5 * modeSize, "There should be five packets in there");
+  NS_TEST_EXPECT_MSG_EQ (p->GetUid (), p3->GetUid (), "Was this the third packet ?");
+
+  p = queue->Dequeue ();
+  p = queue->Dequeue ();
+  p = queue->Dequeue ();
+  p = queue->Dequeue ();
+  p = queue->Dequeue ();
+
+  p = queue->Dequeue ();
+  NS_TEST_EXPECT_MSG_EQ ((p == 0), true, "There are really no packets in there");
+
+
+  // test 2: more data, but with no drops
+  queue = CreateObject<RedQueue> ();
+  minTh = 70 * modeSize;
+  maxTh = 150 * modeSize;
+  qSize = 300 * modeSize;
+  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", mode), true,
+                         "Verify that we can actually set the attribute Mode");
+  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
+                         "Verify that we can actually set the attribute MinTh");
+  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
+                         "Verify that we can actually set the attribute MaxTh");
+  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueLimit", UintegerValue (qSize)), true,
+                         "Verify that we can actually set the attribute QueueLimit");
+  Enqueue (queue, pktSize, 300);
+  RedQueue::Stats st = StaticCast<RedQueue> (queue)->GetStats ();
+  NS_TEST_EXPECT_MSG_EQ (st.unforcedDrop, 0, "There should zero dropped packets due probability mark");
+  NS_TEST_EXPECT_MSG_EQ (st.forcedDrop, 0, "There should zero dropped packets due hardmark mark");
+  NS_TEST_EXPECT_MSG_EQ (st.qLimDrop, 0, "There should zero dropped packets due queue full");
+
+  // save number of drops from tests
+  struct d {
+    uint32_t test3;
+    uint32_t test4;
+    uint32_t test5;
+    uint32_t test6;
+    uint32_t test7;
+  } drop;
+
+
+  // test 3: more data, now drops due QW change
+  queue = CreateObject<RedQueue> ();
+  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", mode), true,
+                         "Verify that we can actually set the attribute Mode");
+  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
+                         "Verify that we can actually set the attribute MinTh");
+  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
+                         "Verify that we can actually set the attribute MaxTh");
+  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueLimit", UintegerValue (qSize)), true,
+                         "Verify that we can actually set the attribute QueueLimit");
+  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.020)), true,
+                         "Verify that we can actually set the attribute QW");
+  Enqueue (queue, pktSize, 300);
+  st = StaticCast<RedQueue> (queue)->GetStats ();
+  drop.test3 = st.unforcedDrop + st.forcedDrop + st.qLimDrop;
+  NS_TEST_EXPECT_MSG_NE (drop.test3, 0, "There should be some dropped packets");
+
+
+  // test 4: reduced maxTh, this causes more drops
+  maxTh = 100 * modeSize;
+  queue = CreateObject<RedQueue> ();
+  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", mode), true,
+                         "Verify that we can actually set the attribute Mode");
+  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
+                         "Verify that we can actually set the attribute MinTh");
+  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
+                         "Verify that we can actually set the attribute MaxTh");
+  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueLimit", UintegerValue (qSize)), true,
+                         "Verify that we can actually set the attribute QueueLimit");
+  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.020)), true,
+                         "Verify that we can actually set the attribute QW");
+  Enqueue (queue, pktSize, 300);
+  st = StaticCast<RedQueue> (queue)->GetStats ();
+  drop.test4 = st.unforcedDrop + st.forcedDrop + st.qLimDrop;
+  NS_TEST_EXPECT_MSG_GT (drop.test4, drop.test3, "Test 4 should have more drops than test 3");
+
+
+  // test 5: change drop probability to a high value (LInterm)
+  maxTh = 150 * modeSize;
+  queue = CreateObject<RedQueue> ();
+  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", mode), true,
+                         "Verify that we can actually set the attribute Mode");
+  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
+                         "Verify that we can actually set the attribute MinTh");
+  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
+                         "Verify that we can actually set the attribute MaxTh");
+  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueLimit", UintegerValue (qSize)), true,
+                         "Verify that we can actually set the attribute QueueLimit");
+  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.020)), true,
+                         "Verify that we can actually set the attribute QW");
+  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("LInterm", DoubleValue (5)), true,
+                         "Verify that we can actually set the attribute LInterm");
+  Enqueue (queue, pktSize, 300);
+  st = StaticCast<RedQueue> (queue)->GetStats ();
+  drop.test5 = st.unforcedDrop + st.forcedDrop + st.qLimDrop;
+  NS_TEST_EXPECT_MSG_GT (drop.test5, drop.test3, "Test 5 should have more drops than test 3");
+
+
+  // test 6: disable Gentle param
+  queue = CreateObject<RedQueue> ();
+  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", mode), true,
+                         "Verify that we can actually set the attribute Mode");
+  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
+                         "Verify that we can actually set the attribute MinTh");
+  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
+                         "Verify that we can actually set the attribute MaxTh");
+  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueLimit", UintegerValue (qSize)), true,
+                         "Verify that we can actually set the attribute QueueLimit");
+  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.020)), true,
+                         "Verify that we can actually set the attribute QW");
+  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Gentle", BooleanValue (false)), true,
+                         "Verify that we can actually set the attribute Gentle");
+  Enqueue (queue, pktSize, 300);
+  st = StaticCast<RedQueue> (queue)->GetStats ();
+  drop.test6 = st.unforcedDrop + st.forcedDrop + st.qLimDrop;
+  NS_TEST_EXPECT_MSG_GT (drop.test6, drop.test3, "Test 6 should have more drops than test 3");
+
+
+  // test 7: disable Wait param
+  queue = CreateObject<RedQueue> ();
+  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", mode), true,
+                         "Verify that we can actually set the attribute Mode");
+  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
+                         "Verify that we can actually set the attribute MinTh");
+  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
+                         "Verify that we can actually set the attribute MaxTh");
+  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueLimit", UintegerValue (qSize)), true,
+                         "Verify that we can actually set the attribute QueueLimit");
+  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.020)), true,
+                         "Verify that we can actually set the attribute QW");
+  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Wait", BooleanValue (false)), true,
+                         "Verify that we can actually set the attribute Wait");
+  Enqueue (queue, pktSize, 300);
+  st = StaticCast<RedQueue> (queue)->GetStats ();
+  drop.test7 = st.unforcedDrop + st.forcedDrop + st.qLimDrop;
+  NS_TEST_EXPECT_MSG_GT (drop.test7, drop.test3, "Test 7 should have more drops than test 3");
+}
+
+void 
+RedQueueTestCase::Enqueue (Ptr<RedQueue> queue, uint32_t size, uint32_t nPkt)
+{
+  for (uint32_t i = 0; i < nPkt; i++)
+    {
+      queue->Enqueue (Create<Packet> (size));
+    }
+}
+
+void
+RedQueueTestCase::DoRun (void)
+{
+  RunRedTest (StringValue ("Packets"));
+  RunRedTest (StringValue ("Bytes"));
+  Simulator::Destroy ();
+
+}
+
+static class RedQueueTestSuite : public TestSuite
+{
+public:
+  RedQueueTestSuite ()
+    : TestSuite ("red-queue", UNIT)
+  {
+    AddTestCase (new RedQueueTestCase ());
+  }
+} g_redQueueTestSuite;
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/network/utils/red-queue.cc	Fri Dec 16 18:51:18 2011 +0100
@@ -0,0 +1,653 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * This code was ported from NS-2.34, with licence:
+ *
+ * Copyright (c) 1990-1997 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 Computer Systems
+ *	Engineering Group at Lawrence Berkeley Laboratory.
+ * 4. Neither the name of the University nor of the Laboratory 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.
+ *
+ *
+ * This port: 
+ *
+ * Copyright © 2011 Marcos Talau
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Marcos Talau (talau@users.sourceforge.net)
+ *
+ * Thanks to: Duy Nguyen<duy@soe.ucsc.edu> by RED efforts in NS3
+ *
+ */
+
+/*
+ * PORT NOTE: Almost all comments have also been ported from NS-2
+ */
+
+#include "ns3/log.h"
+#include "ns3/enum.h"
+#include "ns3/uinteger.h"
+#include "ns3/double.h"
+#include "ns3/simulator.h"
+#include "ns3/abort.h"
+#include "red-queue.h"
+
+NS_LOG_COMPONENT_DEFINE ("RedQueue");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (RedQueue);
+
+TypeId RedQueue::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::RedQueue")
+    .SetParent<Queue> ()
+    .AddConstructor<RedQueue> ()
+    .AddAttribute ("Mode",
+                   "Bytes or packets",
+                   EnumValue (PACKETS),
+                   MakeEnumAccessor (&RedQueue::SetMode),
+                   MakeEnumChecker (BYTES, "Bytes",
+                                    PACKETS, "Packets"))
+    .AddAttribute ("MeanPktSize",
+                   "Average of packet size",
+                   UintegerValue (500),
+                   MakeUintegerAccessor (&RedQueue::m_meanPktSize),
+                   MakeUintegerChecker<uint32_t> ())
+    .AddAttribute ("IdlePktSize",
+                   "Average packet size used during idle times. Used when m_cautions = 3",
+                   UintegerValue (0),
+                   MakeUintegerAccessor (&RedQueue::m_idlePktSize),
+                   MakeUintegerChecker<uint32_t> ())
+    .AddAttribute ("Wait",
+                   "True for waiting between dropped packets",
+                   BooleanValue (true),
+                   MakeBooleanAccessor (&RedQueue::m_isWait),
+                   MakeBooleanChecker ())
+    .AddAttribute ("Gentle",
+                   "True to increases dropping probability slowly when average queue exceeds maxthresh",
+                   BooleanValue (true),
+                   MakeBooleanAccessor (&RedQueue::m_isGentle),
+                   MakeBooleanChecker ())
+    .AddAttribute ("MinTh",
+                   "Minimum average length threshold in packets/bytes",
+                   DoubleValue (5),
+                   MakeDoubleAccessor (&RedQueue::m_minTh),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("MaxTh",
+                   "Maximum average length threshold in packets/bytes",
+                   DoubleValue (15),
+                   MakeDoubleAccessor (&RedQueue::m_maxTh),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("QueueLimit",
+                   "Queue limit in bytes/packets",
+                   UintegerValue (25),
+                   MakeUintegerAccessor (&RedQueue::m_queueLimit),
+                   MakeUintegerChecker<uint32_t> ())
+    .AddAttribute ("QW",
+                   "Queue weight related to the exponential weighted moving average (EWMA)",
+                   DoubleValue (0.002),
+                   MakeDoubleAccessor (&RedQueue::m_qW),
+                   MakeDoubleChecker <double> ())
+    .AddAttribute ("LInterm",
+                   "The maximum probability of dropping a packet",
+                   DoubleValue (50),
+                   MakeDoubleAccessor (&RedQueue::m_lInterm),
+                   MakeDoubleChecker <double> ())
+    .AddAttribute ("Ns1Compat",
+                   "NS-1 compatibility",
+                   BooleanValue (false),
+                   MakeBooleanAccessor (&RedQueue::m_isNs1Compat),
+                   MakeBooleanChecker ())
+    .AddAttribute ("LinkBandwidth", 
+                   "The RED link bandwidth",
+                   DataRateValue (DataRate ("1.5Mbps")),
+                   MakeDataRateAccessor (&RedQueue::m_linkBandwidth),
+                   MakeDataRateChecker ())
+    .AddAttribute ("LinkDelay", 
+                   "The RED link delay",
+                   TimeValue (MilliSeconds (20)),
+                   MakeTimeAccessor (&RedQueue::m_linkDelay),
+                   MakeTimeChecker ())
+  ;
+
+  return tid;
+}
+
+RedQueue::RedQueue () :
+  Queue (),
+  m_packets (),
+  m_bytesInQueue (0),
+  m_hasRedStarted (false)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+RedQueue::~RedQueue ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+void
+RedQueue::SetMode (enum Mode mode)
+{
+  NS_LOG_FUNCTION (mode);
+  m_mode = mode;
+}
+
+RedQueue::Mode
+RedQueue::GetMode (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_mode;
+}
+
+void
+RedQueue::SetQueueLimit (uint32_t lim)
+{
+  NS_LOG_FUNCTION (lim);
+  m_queueLimit = lim;
+}
+
+void
+RedQueue::SetTh (double minTh, double maxTh)
+{
+  NS_LOG_FUNCTION (this << minTh << maxTh);
+  NS_ASSERT (minTh <= maxTh);
+  m_minTh = minTh;
+  m_maxTh = maxTh;
+}
+
+RedQueue::Stats
+RedQueue::GetStats ()
+{
+  return m_stats;
+}
+
+bool
+RedQueue::DoEnqueue (Ptr<Packet> p)
+{
+  NS_LOG_FUNCTION (this << p);
+
+  if (!m_hasRedStarted )
+    {
+      NS_LOG_INFO ("Initializing RED params.");
+      InitializeParams ();
+      m_hasRedStarted = true;
+    }
+
+  uint32_t nQueued = 0;
+
+  if (GetMode () == BYTES)
+    {
+      NS_LOG_DEBUG ("Enqueue in bytes mode");
+      nQueued = m_bytesInQueue;
+    }
+  else if (GetMode () == PACKETS)
+    {
+      NS_LOG_DEBUG ("Enqueue in packets mode");
+      nQueued = m_packets.size ();
+    }
+
+  // simulate number of packets arrival during idle period
+  uint32_t m = 0;
+
+  if (m_idle == 1)
+    {
+      NS_LOG_DEBUG ("RED Queue is idle.");
+      Time now = Simulator::Now ();
+
+      if (m_cautious == 3)
+        {
+          double ptc = m_ptc * m_meanPktSize / m_idlePktSize;
+          m = uint32_t (ptc * (now - m_idleTime).GetSeconds ());
+        }
+      else
+        {
+          m = uint32_t (m_ptc * (now - m_idleTime).GetSeconds ());
+        }
+
+      m_idle = 0;
+    }
+
+  m_qAvg = Estimator (nQueued, m + 1, m_qAvg, m_qW);
+
+  NS_LOG_DEBUG ("\t bytesInQueue  " << m_bytesInQueue << "\tQavg " << m_qAvg);
+  NS_LOG_DEBUG ("\t packetsInQueue  " << m_packets.size () << "\tQavg " << m_qAvg);
+
+  m_count++;
+  m_countBytes += p->GetSize ();
+
+  uint32_t dropType = DTYPE_NONE;
+  if (m_qAvg >= m_minTh && nQueued > 1)
+    {
+      if ((!m_isGentle && m_qAvg >= m_maxTh) ||
+          (m_isGentle && m_qAvg >= 2 * m_maxTh))
+        {
+          NS_LOG_DEBUG ("adding DROP FORCED MARK");
+          dropType = DTYPE_FORCED;
+        }
+      else if (m_old == 0)
+        {
+          /* 
+           * The average queue size has just crossed the
+           * threshold from below to above "minthresh", or
+           * from above "minthresh" with an empty queue to
+           * above "minthresh" with a nonempty queue.
+           */
+          m_count = 1;
+          m_countBytes = p->GetSize ();
+          m_old = 1;
+        }
+      else if (DropEarly (p, nQueued))
+        {
+          NS_LOG_LOGIC ("DropEarly returns 1");
+          dropType = DTYPE_UNFORCED;
+        }
+    }
+  else 
+    {
+      // No packets are being dropped
+      m_vProb = 0.0;
+      m_old = 0;
+    }
+
+  if (nQueued >= m_queueLimit)
+    {
+      NS_LOG_DEBUG ("\t Dropping due to Queue Full " << nQueued);
+      dropType = DTYPE_FORCED;
+      m_stats.qLimDrop++;
+    }
+
+  if (dropType == DTYPE_UNFORCED)
+    {
+      NS_LOG_DEBUG ("\t Dropping due to Prob Mark " << m_qAvg);
+      m_stats.unforcedDrop++;
+      Drop (p);
+      return false;
+    }
+  else if (dropType == DTYPE_FORCED)
+    {
+      NS_LOG_DEBUG ("\t Dropping due to Hard Mark " << m_qAvg);
+      m_stats.forcedDrop++;
+      Drop (p);
+      if (m_isNs1Compat)
+        {
+          m_count = 0;
+          m_countBytes = 0;
+        }
+      return false;
+    }
+
+  m_bytesInQueue += p->GetSize ();
+  m_packets.push_back (p);
+
+  NS_LOG_LOGIC ("Number packets " << m_packets.size ());
+  NS_LOG_LOGIC ("Number bytes " << m_bytesInQueue);
+
+  return true;
+}
+
+/*
+ * Note: if the link bandwidth changes in the course of the
+ * simulation, the bandwidth-dependent RED parameters do not change.
+ * This should be fixed, but it would require some extra parameters,
+ * and didn't seem worth the trouble...
+ */
+void
+RedQueue::InitializeParams (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  NS_ASSERT (m_minTh <= m_maxTh);
+  m_stats.forcedDrop = 0;
+  m_stats.unforcedDrop = 0;
+  m_stats.qLimDrop = 0;
+
+  m_cautious = 0;
+  m_ptc = m_linkBandwidth.GetBitRate () / (8.0 * m_meanPktSize);
+
+  m_qAvg = 0.0;
+  m_count = 0;
+  m_countBytes = 0;
+  m_old = 0;
+  m_idle = 1;
+
+  double th_diff = (m_maxTh - m_minTh);
+  if (th_diff == 0)
+    {
+      th_diff = 1.0; 
+    }
+  m_vA = 1.0 / th_diff;
+  m_curMaxP = 1.0 / m_lInterm;
+  m_vB = -m_minTh / th_diff;
+
+  if (m_isGentle)
+    {
+      m_vC = (1.0 - m_curMaxP) / m_maxTh;
+      m_vD = 2.0 * m_curMaxP - 1.0;
+    }
+  m_idleTime = NanoSeconds (0);
+
+/*
+ * If m_qW=0, set it to a reasonable value of 1-exp(-1/C)
+ * This corresponds to choosing m_qW to be of that value for
+ * which the packet time constant -1/ln(1-m)qW) per default RTT 
+ * of 100ms is an order of magnitude more than the link capacity, C.
+ *
+ * If m_qW=-1, then the queue weight is set to be a function of
+ * the bandwidth and the link propagation delay.  In particular, 
+ * the default RTT is assumed to be three times the link delay and 
+ * transmission delay, if this gives a default RTT greater than 100 ms. 
+ *
+ * If m_qW=-2, set it to a reasonable value of 1-exp(-10/C).
+ */
+  if (m_qW == 0.0)
+    {
+      m_qW = 1.0 - exp (-1.0 / m_ptc);
+    }
+  else if (m_qW == -1.0)
+    {
+      double rtt = 3.0 * (m_linkDelay.GetSeconds () + 1.0 / m_ptc);
+
+      if (rtt < 0.1)
+        {
+          rtt = 0.1;
+        }
+      m_qW = 1.0 - exp (-1.0 / (10 * rtt * m_ptc));
+    }
+  else if (m_qW == -2.0)
+    {
+      m_qW = 1.0 - exp (-10.0 / m_ptc);
+    }
+
+  // TODO: implement adaptive RED
+
+  NS_LOG_DEBUG ("\tm_delay " << m_linkDelay.GetSeconds () << "; m_isWait " 
+                             << m_isWait << "; m_qW " << m_qW << "; m_ptc " << m_ptc
+                             << "; m_minTh " << m_minTh << "; m_maxTh " << m_maxTh
+                             << "; m_isGentle " << m_isGentle << "; th_diff " << th_diff
+                             << "; lInterm " << m_lInterm << "; va " << m_vA <<  "; cur_max_p "
+                             << m_curMaxP << "; v_b " << m_vB <<  "; m_vC "
+                             << m_vC << "; m_vD " <<  m_vD);
+}
+
+// Compute the average queue size
+double
+RedQueue::Estimator (uint32_t nQueued, uint32_t m, double qAvg, double qW)
+{
+  NS_LOG_FUNCTION (this << nQueued << m << qAvg << qW);
+  double newAve;
+
+  newAve = qAvg;
+  while (--m >= 1)
+    {
+      newAve *= 1.0 - qW;
+    }
+  newAve *= 1.0 - qW;
+  newAve += qW * nQueued;
+
+  // TODO: implement adaptive RED
+
+  return newAve;
+}
+
+// Check if packet p needs to be dropped due to probability mark
+uint32_t
+RedQueue::DropEarly (Ptr<Packet> p, uint32_t qSize)
+{
+  NS_LOG_FUNCTION (this << p << qSize);
+  m_vProb1 = CalculatePNew (m_qAvg, m_maxTh, m_isGentle, m_vA, m_vB, m_vC, m_vD, m_curMaxP);
+  m_vProb = ModifyP (m_vProb1, m_count, m_countBytes, m_meanPktSize, m_isWait, p->GetSize ());
+
+  // Drop probability is computed, pick random number and act
+  if (m_cautious == 1)
+    {
+      /*
+       * Don't drop/mark if the instantaneous queue is much below the average.
+       * For experimental purposes only.
+       * pkts: the number of packets arriving in 50 ms
+       */
+      double pkts = m_ptc * 0.05;
+      double fraction = pow ((1 - m_qW), pkts);
+
+      if ((double) qSize < fraction * m_qAvg)
+        {
+          // Queue could have been empty for 0.05 seconds
+          return 0;
+        }
+    }
+
+  UniformVariable uV;
+  double u = uV.GetValue ();
+
+  if (m_cautious == 2)
+    {
+      /*
+       * Decrease the drop probability if the instantaneous
+       * queue is much below the average.
+       * For experimental purposes only.
+       * pkts: the number of packets arriving in 50 ms
+       */
+      double pkts = m_ptc * 0.05;
+      double fraction = pow ((1 - m_qW), pkts);
+      double ratio = qSize / (fraction * m_qAvg);
+
+      if (ratio < 1.0)
+        {
+          u *= 1.0 / ratio;
+        }
+    }
+
+  if (u <= m_vProb)
+    {
+      NS_LOG_LOGIC ("u <= m_vProb; u " << u << "; m_vProb " << m_vProb);
+
+      // DROP or MARK
+      m_count = 0;
+      m_countBytes = 0;
+      // TODO: Implement set bit to mark
+
+      return 1; // drop
+    }
+
+  return 0; // no drop/mark
+}
+
+// Returns a probability using these function parameters for the DropEarly funtion
+double
+RedQueue::CalculatePNew (double qAvg, double maxTh, bool isGentle, double vA,
+                         double vB, double vC, double vD, double maxP)
+{
+  NS_LOG_FUNCTION (this << qAvg << maxTh << isGentle << vA << vB << vC << vD << maxP);
+  double p;
+
+  if (isGentle && qAvg >= maxTh)
+    {
+      // p ranges from maxP to 1 as the average queue
+      // Size ranges from maxTh to twice maxTh
+      p = vC * qAvg + vD;
+    }
+  else if (!isGentle && qAvg >= maxTh)
+    {
+      /* 
+       * OLD: p continues to range linearly above max_p as
+       * the average queue size ranges above th_max.
+       * NEW: p is set to 1.0
+       */
+      p = 1.0;
+    }
+  else
+    {
+      /*
+       * p ranges from 0 to max_p as the average queue size ranges from
+       * th_min to th_max
+       */
+      p = vA * qAvg + vB;
+      p *= maxP;
+    }
+
+  if (p > 1.0)
+    {
+      p = 1.0;
+    }
+
+  return p;
+}
+
+// Returns a probability using these function parameters for the DropEarly funtion
+double 
+RedQueue::ModifyP (double p, uint32_t count, uint32_t countBytes,
+                   uint32_t meanPktSize, bool isWait, uint32_t size)
+{
+  NS_LOG_FUNCTION (this << p << count << countBytes << meanPktSize << isWait << size);
+  double count1 = (double) count;
+
+  if (GetMode () == BYTES)
+    {
+      count1 = (double) (countBytes / meanPktSize);
+    }
+
+  if (isWait)
+    {
+      if (count1 * p < 1.0)
+        {
+          p = 0.0;
+        }
+      else if (count1 * p < 2.0)
+        {
+          p /= (2.0 - count1 * p);
+        }
+      else
+        {
+          p = 1.0;
+        }
+    }
+  else
+    {
+      if (count1 * p < 1.0)
+        {
+          p /= (1.0 - count1 * p);
+        }
+      else
+        {
+          p = 1.0;
+        }
+    }
+
+  if ((GetMode () == BYTES) && (p < 1.0))
+    {
+      p = (p * size) / meanPktSize;
+    }
+
+  if (p > 1.0)
+    {
+      p = 1.0;
+    }
+
+  return p;
+}
+
+uint32_t
+RedQueue::GetQueueSize (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  if (GetMode () == BYTES)
+    {
+      return m_bytesInQueue;
+    }
+  else if (GetMode () == PACKETS)
+    {
+      return m_packets.size ();
+    }
+  else
+    {
+      NS_ABORT_MSG ("Unknown RED mode.");
+    }
+}
+
+Ptr<Packet>
+RedQueue::DoDequeue (void)
+{
+  NS_LOG_FUNCTION (this);
+
+  if (m_packets.empty ())
+    {
+      NS_LOG_LOGIC ("Queue empty");
+      m_idle = 1;
+      m_idleTime = Simulator::Now ();
+
+      return 0;
+    }
+  else
+    {
+      m_idle = 0;
+      Ptr<Packet> p = m_packets.front ();
+      m_packets.pop_front ();
+      m_bytesInQueue -= p->GetSize ();
+
+      NS_LOG_LOGIC ("Popped " << p);
+
+      NS_LOG_LOGIC ("Number packets " << m_packets.size ());
+      NS_LOG_LOGIC ("Number bytes " << m_bytesInQueue);
+
+      return p;
+    }
+}
+
+Ptr<const Packet>
+RedQueue::DoPeek (void) const
+{
+  NS_LOG_FUNCTION (this);
+  if (m_packets.empty ())
+    {
+      NS_LOG_LOGIC ("Queue empty");
+      return 0;
+    }
+
+  Ptr<Packet> p = m_packets.front ();
+
+  NS_LOG_LOGIC ("Number packets " << m_packets.size ());
+  NS_LOG_LOGIC ("Number bytes " << m_bytesInQueue);
+
+  return p;
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/network/utils/red-queue.h	Fri Dec 16 18:51:18 2011 +0100
@@ -0,0 +1,277 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * This code was ported from NS-2.34, with licence:
+ *
+ * Copyright (c) 1990-1997 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 Computer Systems
+ *	Engineering Group at Lawrence Berkeley Laboratory.
+ * 4. Neither the name of the University nor of the Laboratory 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.
+ *
+ *
+ * This port:
+ *
+ * Copyright © 2011 Marcos Talau
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Marcos Talau (talau@users.sourceforge.net)
+ *
+ * Thanks to: Duy Nguyen<duy@soe.ucsc.edu> by RED efforts in NS3
+ *
+ */
+
+/*
+ * PORT NOTE: Almost all comments also been ported from NS-2
+ * This implementation aims to be close to the results cited in [0]
+ * [0] S.Floyd, K.Fall http://icir.org/floyd/papers/redsims.ps
+ */
+
+#ifndef RED_QUEUE_H
+#define RED_QUEUE_H
+
+#include <queue>
+#include "ns3/packet.h"
+#include "ns3/queue.h"
+#include "ns3/nstime.h"
+#include "ns3/random-variable.h"
+#include "ns3/boolean.h"
+#include "ns3/data-rate.h"
+#include "ns3/nstime.h"
+
+namespace ns3 {
+
+class TraceContainer;
+
+/*
+ * \ingroup queue
+ *
+ * \brief A RED packet queue
+ */
+class RedQueue : public Queue
+{
+public:
+  static TypeId GetTypeId (void);
+  /*
+   * \brief RedQueue Constructor
+   *
+   * Create a RED queue
+   */
+  RedQueue ();
+
+  /*
+   * \brief Destructor
+   *
+   * Destructor
+   */ 
+  virtual ~RedQueue ();
+
+  /*
+   * \brief Stats
+   *
+   */
+  typedef struct
+  {
+    // Early probability drops
+    uint32_t unforcedDrop;
+    // Forced drops, qavg > max threshold
+    uint32_t forcedDrop;
+    // Drops due to queue limits
+    uint32_t qLimDrop;
+  } Stats;
+
+  /* 
+   * \brief Drop types
+   *
+   */
+  enum
+  {
+    DTYPE_NONE,        // Ok, no drop
+    DTYPE_FORCED,      // A "forced" drop
+    DTYPE_UNFORCED,    // An "unforced" (random) drop
+  };
+
+  /*
+   * \brief Enumeration of the modes supported in the class.
+   *
+   */
+  enum Mode
+  {
+    ILLEGAL,     // Mode not set
+    PACKETS,     // Use number of packets for maximum queue size
+    BYTES,       // Use number of bytes for maximum queue size
+  };
+
+  /*
+   * \brief Set the operating mode of this queue.
+   *  Set operating mode
+   *
+   * \param mode The operating mode of this queue.
+   */
+  void SetMode (RedQueue::Mode mode);
+
+  /*
+   * \brief Get the encapsulation mode of this queue.
+   * Get the encapsulation mode of this queue
+   *
+   * \returns The encapsulation mode of this queue.
+   */
+  RedQueue::Mode  GetMode (void);
+
+  /*
+   * \brief Get the current value of the queue in bytes or packets.
+   *
+   * \returns The queue size in bytes or packets.
+   */
+  uint32_t GetQueueSize (void);
+
+  /*
+   * \brief Set the limit of the queue.
+   *
+   * \param lim The limit in bytes or packets.
+   */
+  void SetQueueLimit (uint32_t lim);
+
+  /*
+   * \brief Set the thresh limits of RED.
+   *
+   * \param min Minimum thresh in bytes or packets.
+   * \param max Maximum thresh in bytes or packets.
+   */
+  void SetTh (double minTh, double maxTh);
+
+  /*
+   * \brief Get the RED statistics after running.
+   *
+   * \returns The drop statistics.
+   */
+  Stats GetStats ();
+
+private:
+  virtual bool DoEnqueue (Ptr<Packet> p);
+  virtual Ptr<Packet> DoDequeue (void);
+  virtual Ptr<const Packet> DoPeek (void) const;
+
+  // ...
+  void InitializeParams (void);
+  // Compute the average queue size
+  double Estimator (uint32_t nQueued, uint32_t m, double qAvg, double qW);
+  // Check if packet p needs to be dropped due to probability mark
+  uint32_t DropEarly (Ptr<Packet> p, uint32_t qSize);
+  // Returns a probability using these function parameters for the DropEarly funtion
+  double CalculatePNew (double qAvg, double maxTh, bool gentle, double vA,
+                        double vB, double vC, double vD, double maxP);
+  // Returns a probability using these function parameters for the DropEarly funtion
+  double ModifyP (double p, uint32_t count, uint32_t countBytes,
+                  uint32_t meanPktSize, bool wait, uint32_t size);
+
+  std::list<Ptr<Packet> > m_packets;
+
+  uint32_t m_bytesInQueue;
+  bool m_hasRedStarted;
+  Stats m_stats;
+
+  // ** Variables supplied by user
+  // Bytes or packets?
+  Mode m_mode;
+  // Avg pkt size
+  uint32_t m_meanPktSize;
+  // Avg pkt size used during idle times
+  uint32_t m_idlePktSize;
+  // True for waiting between dropped packets
+  bool m_isWait;
+  // True to increases dropping prob. slowly when ave queue exceeds maxthresh
+  bool m_isGentle;
+  // Min avg length threshold (bytes)
+  double m_minTh;
+  // Max avg length threshold (bytes), should be >= 2*minTh
+  double m_maxTh;
+  // Queue limit in bytes / packets
+  uint32_t m_queueLimit;
+  // Queue weight given to cur q size sample
+  double m_qW;
+  // The max probability of dropping a packet
+  double m_lInterm;
+  // Ns-1 compatibility
+  bool m_isNs1Compat;
+  // Link bandwidth
+  DataRate m_linkBandwidth;
+  // Link delay
+  Time m_linkDelay;
+
+  // ** Variables maintained by RED
+  // Prob. of packet drop before "count"
+  double m_vProb1;
+  // v_prob = v_a * v_ave + v_b
+  double m_vA;
+  double m_vB;
+  // Used for "gentle" mode
+  double m_vC;
+  // Used for "gentle" mode
+  double m_vD;
+  // Current max_p
+  double m_curMaxP;
+  // Prob. of packet drop
+  double m_vProb;
+  // # of bytes since last drop
+  uint32_t m_countBytes;
+  // 0 when average queue first exceeds thresh
+  uint32_t m_old;
+  // 0/1 idle status
+  uint32_t m_idle;
+  // packet time constant in packets/second
+  double m_ptc;
+  // Average queue length
+  double m_qAvg;
+  // number of packets since last random number generation
+  uint32_t m_count;
+  /*
+   * 0 for default RED
+   * 1 experimental (see red-queue.cc)
+   * 2 experimental (see red-queue.cc)
+   * 3 use Idle packet size in the ptc
+   */
+  uint32_t m_cautious;
+  // Start of current idle period
+  Time m_idleTime;
+};
+
+}; // namespace ns3
+
+#endif // RED_QUEUE_H
--- a/src/network/wscript	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/network/wscript	Fri Dec 16 18:51:18 2011 +0100
@@ -47,6 +47,7 @@
         'utils/pcap-file-wrapper.cc',
         'utils/queue.cc',
         'utils/radiotap-header.cc',
+        'utils/red-queue.cc',
         'utils/simple-channel.cc',
         'utils/simple-net-device.cc',
         'helper/application-container.cc',
@@ -64,6 +65,7 @@
         'test/packet-test-suite.cc',
         'test/packet-metadata-test.cc',
         'test/pcap-file-test-suite.cc',
+        'test/red-queue-test-suite.cc',
         'test/sequence-number-test-suite.cc',
         ]
 
@@ -115,6 +117,7 @@
         'utils/generic-phy.h',
         'utils/queue.h',
         'utils/radiotap-header.h',
+        'utils/red-queue.h',
         'utils/sequence-number.h',
         'utils/sgi-hashmap.h',
         'utils/simple-channel.h',
--- a/src/olsr/model/olsr-repositories.h	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/olsr/model/olsr-repositories.h	Fri Dec 16 18:51:18 2011 +0100
@@ -21,8 +21,7 @@
  */
 
 ///
-/// \file	olsr-repositories.h
-/// \brief	Here are defined all data structures needed by an OLSR node.
+/// \brief Here are defined all data structures needed by an OLSR node.
 ///
 
 #ifndef OLSR_REPOSITORIES_H
--- a/src/olsr/model/olsr-routing-protocol.cc	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/olsr/model/olsr-routing-protocol.cc	Fri Dec 16 18:51:18 2011 +0100
@@ -22,8 +22,7 @@
 
 
 ///
-/// \file	OLSR.cc
-/// \brief	Implementation of OLSR agent and related classes.
+/// \brief Implementation of OLSR agent and related classes.
 ///
 /// This is the main file of this software because %OLSR's behaviour is
 /// implemented here.
@@ -499,7 +498,6 @@
                               receiverIfaceAddr, inetSourceAddr.GetIpv4 ());
             }
         }
-	
     }
 
   // After processing all OLSR messages, we must recompute the routing table
@@ -573,7 +571,6 @@
   // MPR computation should be done for each interface. See section 8.3.1
   // (RFC 3626) for details.
   MprSet mprSet;
-	
 
   // N is the subset of neighbors of the node, which are
   // neighbor "of the interface I"
@@ -586,7 +583,7 @@
           N.push_back (*neighbor);
         }
     }
-	
+
   // N2 is the set of 2-hop neighbors reachable from "the interface
   // I", excluding:
   // (i)   the nodes only reachable by members of N with willingness WILL_NEVER
@@ -681,7 +678,7 @@
 
   // 2. Calculate D(y), where y is a member of N, for all nodes in N.
   // (we do this later)
-	
+
   // 3. Add to the MPR set those nodes in N, which are the *only*
   // nodes to provide reachability to a node in N2.
   std::set<Ipv4Address> coveredTwoHopNeighbors;
@@ -734,7 +731,7 @@
           twoHopNeigh++;
         }
     }
-	
+
   // 4. While there exist nodes in N2 which are not covered by at
   // least one node in the MPR set:
   while (N2.begin () != N2.end ())
@@ -882,7 +879,7 @@
 
   // 1. All the entries from the routing table are removed.
   Clear ();
-	
+
   // 2. The new routing entries are added starting with the
   // symmetric neighbors (h=1) as the destination nodes.
   const NeighborSet &neighborSet = m_state.GetNeighbors ();
@@ -1080,9 +1077,9 @@
 
   // 4. For each entry in the multiple interface association base
   // where there exists a routing entry such that:
-  //	R_dest_addr  == I_main_addr  (of the multiple interface association entry)
+  // R_dest_addr == I_main_addr (of the multiple interface association entry)
   // AND there is no routing entry such that:
-  //	R_dest_addr  == I_iface_addr
+  // R_dest_addr == I_iface_addr
   const IfaceAssocSet &ifaceAssocSet = m_state.GetIfaceAssocSet ();
   for (IfaceAssocSet::const_iterator it = ifaceAssocSet.begin ();
        it != ifaceAssocSet.end (); it++)
@@ -1268,13 +1265,13 @@
 {
   const olsr::MessageHeader::Tc &tc = msg.GetTc ();
   Time now = Simulator::Now ();
-	
+
   // 1. If the sender interface of this message is not in the symmetric
   // 1-hop neighborhood of this node, the message MUST be discarded.
   const LinkTuple *link_tuple = m_state.FindSymLinkTuple (senderIface, now);
   if (link_tuple == NULL)
     return;
-	
+
   // 2. If there exist some tuple in the topology set where:
   //    T_last_addr == originator address AND
   //    T_seq       >  ANSN,
@@ -1284,10 +1281,10 @@
     m_state.FindNewerTopologyTuple (msg.GetOriginatorAddress (), tc.ansn);
   if (topologyTuple != NULL)
     return;
-	
+
   // 3. All tuples in the topology set where:
-  //	T_last_addr == originator address AND
-  //	T_seq       <  ANSN
+  //    T_last_addr == originator address AND
+  //    T_seq       <  ANSN
   // MUST be removed from the topology set.
   m_state.EraseOlderTopologyTuples (msg.GetOriginatorAddress (), tc.ansn);
 
@@ -1298,10 +1295,10 @@
     {
       const Ipv4Address &addr = *i;
       // 4.1. If there exist some tuple in the topology set where:
-      //        T_dest_addr == advertised neighbor main address, AND
-      //        T_last_addr == originator address,
+      //      T_dest_addr == advertised neighbor main address, AND
+      //      T_last_addr == originator address,
       // then the holding time of that tuple MUST be set to:
-      //        T_time      =  current time + validity time.
+      //      T_time      =  current time + validity time.
       TopologyTuple *topologyTuple =
         m_state.FindTopologyTuple (addr, msg.GetOriginatorAddress ());
 
@@ -1313,10 +1310,10 @@
         {
           // 4.2. Otherwise, a new tuple MUST be recorded in the topology
           // set where:
-          //	T_dest_addr = advertised neighbor main address,
-          //	T_last_addr = originator address,
-          //	T_seq       = ANSN,
-          //	T_time      = current time + validity time.
+          //      T_dest_addr = advertised neighbor main address,
+          //      T_last_addr = originator address,
+          //      T_seq       = ANSN,
+          //      T_time      = current time + validity time.
           TopologyTuple topologyTuple;;
           topologyTuple.destAddr = addr;
           topologyTuple.lastAddr = msg.GetOriginatorAddress ();
@@ -1376,7 +1373,7 @@
                     " the message MUST be discarded.");
       return;
     }
-	
+
   // 2. For each interface address listed in the MID message
   for (std::vector<Ipv4Address>::const_iterator i = mid.interfaceAddresses.begin ();
        i != mid.interfaceAddresses.end (); i++)
@@ -1526,7 +1523,7 @@
                     " from " << olsrMessage.GetOriginatorAddress () << " because it is duplicated");
       return;
     }
-	
+
   // If the sender interface address is an interface address
   // of a MPR selector of this node and ttl is greater than 1,
   // the message must be retransmitted
@@ -1545,7 +1542,7 @@
           retransmitted = true;
         }
     }
-	
+
   // Update duplicate tuple...
   if (duplicated != NULL)
     {
@@ -1680,7 +1677,7 @@
 
   std::vector<olsr::MessageHeader::Hello::LinkMessage>
   &linkMessages = hello.linkMessages;
-	
+
   const LinkSet &links = m_state.GetLinks ();
   for (LinkSet::const_iterator link_tuple = links.begin ();
        link_tuple != links.end (); link_tuple++)
@@ -1921,7 +1918,7 @@
 ///        in HNA messages sent by the node.
 ///        If this method is called more than once, entries from the old
 ///        association are deleted before entries from the new one are added.
-/// \param the Ipv4StaticRouting routing table to be associated.
+/// \param routingTable the Ipv4StaticRouting routing table to be associated.
 ///
 void
 RoutingProtocol::SetRoutingTableAssociation (Ptr<Ipv4StaticRouting> routingTable)
@@ -1983,8 +1980,8 @@
 }
 
 ///
-/// \brief	Updates Link Set according to a new received HELLO message (following RFC 3626
-///		specification). Neighbor Set is also updated if needed.
+/// \brief Updates Link Set according to a new received HELLO message
+/// (following RFC 3626 specification). Neighbor Set is also updated if needed.
 void
 RoutingProtocol::LinkSensing (const olsr::MessageHeader &msg,
                               const olsr::MessageHeader::Hello &hello,
@@ -1997,7 +1994,7 @@
   NS_LOG_DEBUG ("@" << now.GetSeconds () << ": Olsr node " << m_mainAddress
                     << ": LinkSensing(receiverIface=" << receiverIface
                     << ", senderIface=" << senderIface << ") BEGIN");
-	
+
   NS_ASSERT (msg.GetVTime () > Seconds (0));
   LinkTuple *link_tuple = m_state.FindLinkTuple (senderIface);
   if (link_tuple == NULL)
@@ -2017,7 +2014,7 @@
       NS_LOG_LOGIC ("Existing link tuple already exists => will update it");
       updated = true;
     }
-	
+
   link_tuple->asymTime = now + msg.GetVTime ();
   for (std::vector<olsr::MessageHeader::Hello::LinkMessage>::const_iterator linkMessage =
          hello.linkMessages.begin ();
@@ -2118,8 +2115,8 @@
 }
 
 ///
-/// \brief	Updates the Neighbor Set according to the information contained in a new received
-///		HELLO message (following RFC 3626).
+/// \brief Updates the Neighbor Set according to the information contained in
+/// a new received HELLO message (following RFC 3626).
 void
 RoutingProtocol::PopulateNeighborSet (const olsr::MessageHeader &msg,
                                       const olsr::MessageHeader::Hello &hello)
@@ -2133,8 +2130,8 @@
 
 
 ///
-/// \brief	Updates the 2-hop Neighbor Set according to the information contained in a new
-///		received HELLO message (following RFC 3626).
+/// \brief Updates the 2-hop Neighbor Set according to the information contained
+/// in a new received HELLO message (following RFC 3626).
 void
 RoutingProtocol::PopulateTwoHopNeighborSet (const olsr::MessageHeader &msg,
                                             const olsr::MessageHeader::Hello &hello)
@@ -2142,7 +2139,7 @@
   Time now = Simulator::Now ();
 
   NS_LOG_DEBUG ("Olsr node " << m_mainAddress << ": PopulateTwoHopNeighborSet BEGIN");
-	
+
   for (LinkSet::const_iterator link_tuple = m_state.GetLinks ().begin ();
        link_tuple != m_state.GetLinks ().end (); link_tuple++)
     {
@@ -2245,8 +2242,8 @@
 
 
 ///
-/// \brief	Updates the MPR Selector Set according to the information contained in a new
-///		received HELLO message (following RFC 3626).
+/// \brief Updates the MPR Selector Set according to the information contained in
+/// a new received HELLO message (following RFC 3626).
 void
 RoutingProtocol::PopulateMprSelectorSet (const olsr::MessageHeader &msg,
                                          const olsr::MessageHeader::Hello &hello)
@@ -2254,7 +2251,7 @@
   NS_LOG_FUNCTION (this);
 
   Time now = Simulator::Now ();
-	
+
   typedef std::vector<olsr::MessageHeader::Hello::LinkMessage> LinkMessageVec;
   for (LinkMessageVec::const_iterator linkMessage = hello.linkMessages.begin ();
        linkMessage != hello.linkMessages.end ();
@@ -2305,9 +2302,9 @@
 
 #if 0
 ///
-/// \brief	Drops a given packet because it couldn't be delivered to the corresponding
-///		destination by the MAC layer. This may cause a neighbor loss, and appropiate
-///		actions are then taken.
+/// \brief Drops a given packet because it couldn't be delivered to the corresponding
+/// destination by the MAC layer. This may cause a neighbor loss, and appropiate
+/// actions are then taken.
 ///
 /// \param p the packet which couldn't be delivered by the MAC layer.
 ///
@@ -2316,17 +2313,17 @@
   double now              = Simulator::Now ();
   struct hdr_ip* ih       = HDR_IP (p);
   struct hdr_cmn* ch      = HDR_CMN (p);
-	
+
   debug ("%f: Node %d MAC Layer detects a breakage on link to %d\n",
          now,
          OLSR::node_id (ra_addr ()),
          OLSR::node_id (ch->next_hop ()));
-	
+
   if ((u_int32_t)ih->daddr () == IP_BROADCAST) {
       drop (p, DROP_RTR_MAC_CALLBACK);
       return;
     }
-	
+
   OLSR_link_tuple* link_tuple = state_.find_link_tuple (ch->next_hop ());
   if (link_tuple != NULL) {
       link_tuple->lost_time () = now + OLSR_NEIGHB_HOLD_TIME;
@@ -2431,8 +2428,8 @@
 }
 
 ///
-/// \brief	This function is invoked when a link tuple is updated. Its aim is to
-///		also update the corresponding neighbor tuple if it is needed.
+/// \brief This function is invoked when a link tuple is updated. Its aim is to
+/// also update the corresponding neighbor tuple if it is needed.
 ///
 /// \param tuple the link tuple which has been updated.
 ///
@@ -2525,7 +2522,7 @@
 //         OLSR::node_id(ra_addr()),
 //         OLSR::node_id(tuple->neighborMainAddr),
 //         ((tuple->status() == OLSR_STATUS_SYM) ? "sym" : "not_sym"));
-	
+
   m_state.EraseNeighborTuple (tuple);
   IncrementAnsn ();
 }
@@ -2987,7 +2984,7 @@
 
 ///
 /// \brief Deletes the entry whose destination address is given.
-/// \param dest	address of the destination node.
+/// \param dest address of the destination node.
 ///
 void
 RoutingProtocol::RemoveEntry (Ipv4Address const &dest)
@@ -2997,9 +2994,9 @@
 
 ///
 /// \brief Looks up an entry for the specified destination address.
-/// \param dest	destination address.
+/// \param dest destination address.
 /// \param outEntry output parameter to hold the routing entry result, if fuond
-/// \return	true if found, false if not found
+/// \return true if found, false if not found
 ///
 bool
 RoutingProtocol::Lookup (Ipv4Address const &dest,
@@ -3016,8 +3013,8 @@
 }
 
 ///
-/// \brief	Finds the appropiate entry which must be used in order to forward
-///		a data packet to a next hop (given a destination).
+/// \brief Finds the appropiate entry which must be used in order to forward
+/// a data packet to a next hop (given a destination).
 ///
 /// Imagine a routing table like this: [A,B] [B,C] [C,C]; being each pair of the
 /// form [dest addr,next-hop addr]. In this case, if this function is invoked with
@@ -3025,11 +3022,11 @@
 /// to forward a data packet destined to A. That is, C is a neighbor of this node,
 /// but B isn't. This function finds the appropiate neighbor for forwarding a packet.
 ///
-/// \param entry	the routing table entry which indicates the destination node
-///			we are interested in.
-/// \return		the appropiate routing table entry which indicates the next
-///			hop which must be used for forwarding a data packet, or NULL
-///			if there is no such entry.
+/// \param entry the routing table entry which indicates the destination node
+/// we are interested in.
+/// \return the appropiate routing table entry which indicates the next
+/// hop which must be used for forwarding a data packet, or NULL
+/// if there is no such entry.
 ///
 bool
 RoutingProtocol::FindSendEntry (RoutingTableEntry const &entry,
@@ -3239,10 +3236,10 @@
 ///
 /// If an entry for the given destination existed, it is deleted and freed.
 ///
-/// \param dest		address of the destination node.
-/// \param next		address of the next hop node.
-/// \param iface	address of the local interface.
-/// \param dist		distance to the destination node.
+/// \param dest address of the destination node.
+/// \param next address of the next hop node.
+/// \param iface address of the local interface.
+/// \param dist distance to the destination node.
 ///
 void
 RoutingProtocol::AddEntry (Ipv4Address const &dest,
@@ -3348,7 +3345,7 @@
 #endif  //NS3_LOG_ENABLE
 }
 
-}
-}  // namespace olsr, ns3
-
-
+} // namespace olsr
+} // namespace ns3
+
+
--- a/src/olsr/model/olsr-state.cc	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/olsr/model/olsr-state.cc	Fri Dec 16 18:51:18 2011 +0100
@@ -21,7 +21,7 @@
  */
 
 ///
-/// \file	OlsrState.cc
+/// \file	olsr-state.cc
 /// \brief	Implementation of all functions needed for manipulating the internal
 ///		state of an OLSR node.
 ///
Binary file src/olsr/test/bug780-2-0.pcap has changed
--- a/src/propagation/bindings/modulegen__gcc_ILP32.py	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/propagation/bindings/modulegen__gcc_ILP32.py	Fri Dec 16 18:51:18 2011 +0100
@@ -50,6 +50,10 @@
     module.add_class('TraceSourceInformation', import_from_module='ns.core', outer_class=root_module['ns3::TypeId'])
     ## random-variable.h (module 'core'): ns3::UniformVariable [class]
     module.add_class('UniformVariable', import_from_module='ns.core', parent=root_module['ns3::RandomVariable'])
+    ## vector.h (module 'core'): ns3::Vector2D [class]
+    module.add_class('Vector2D', import_from_module='ns.core')
+    ## vector.h (module 'core'): ns3::Vector3D [class]
+    module.add_class('Vector3D', import_from_module='ns.core')
     ## random-variable.h (module 'core'): ns3::WeibullVariable [class]
     module.add_class('WeibullVariable', import_from_module='ns.core', parent=root_module['ns3::RandomVariable'])
     ## random-variable.h (module 'core'): ns3::ZetaVariable [class]
@@ -146,6 +150,8 @@
     module.add_class('LogDistancePropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
     ## propagation-loss-model.h (module 'propagation'): ns3::MatrixPropagationLossModel [class]
     module.add_class('MatrixPropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
+    ## mobility-model.h (module 'mobility'): ns3::MobilityModel [class]
+    module.add_class('MobilityModel', import_from_module='ns.mobility', parent=root_module['ns3::Object'])
     ## propagation-loss-model.h (module 'propagation'): ns3::NakagamiPropagationLossModel [class]
     module.add_class('NakagamiPropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
     ## random-variable.h (module 'core'): ns3::RandomVariableChecker [class]
@@ -160,6 +166,26 @@
     module.add_class('TypeIdChecker', import_from_module='ns.core', parent=root_module['ns3::AttributeChecker'])
     ## type-id.h (module 'core'): ns3::TypeIdValue [class]
     module.add_class('TypeIdValue', import_from_module='ns.core', parent=root_module['ns3::AttributeValue'])
+    ## vector.h (module 'core'): ns3::Vector2DChecker [class]
+    module.add_class('Vector2DChecker', import_from_module='ns.core', parent=root_module['ns3::AttributeChecker'])
+    ## vector.h (module 'core'): ns3::Vector2DValue [class]
+    module.add_class('Vector2DValue', import_from_module='ns.core', parent=root_module['ns3::AttributeValue'])
+    ## vector.h (module 'core'): ns3::Vector3DChecker [class]
+    module.add_class('Vector3DChecker', import_from_module='ns.core', parent=root_module['ns3::AttributeChecker'])
+    ## vector.h (module 'core'): ns3::Vector3DValue [class]
+    module.add_class('Vector3DValue', import_from_module='ns.core', parent=root_module['ns3::AttributeValue'])
+    typehandlers.add_type_alias('ns3::Vector3DValue', 'ns3::VectorValue')
+    typehandlers.add_type_alias('ns3::Vector3DValue*', 'ns3::VectorValue*')
+    typehandlers.add_type_alias('ns3::Vector3DValue&', 'ns3::VectorValue&')
+    module.add_typedef(root_module['ns3::Vector3DValue'], 'VectorValue')
+    typehandlers.add_type_alias('ns3::Vector3D', 'ns3::Vector')
+    typehandlers.add_type_alias('ns3::Vector3D*', 'ns3::Vector*')
+    typehandlers.add_type_alias('ns3::Vector3D&', 'ns3::Vector&')
+    module.add_typedef(root_module['ns3::Vector3D'], 'Vector')
+    typehandlers.add_type_alias('ns3::Vector3DChecker', 'ns3::VectorChecker')
+    typehandlers.add_type_alias('ns3::Vector3DChecker*', 'ns3::VectorChecker*')
+    typehandlers.add_type_alias('ns3::Vector3DChecker&', 'ns3::VectorChecker&')
+    module.add_typedef(root_module['ns3::Vector3DChecker'], 'VectorChecker')
     
     ## Register a nested module for the namespace FatalImpl
     
@@ -186,6 +212,8 @@
     register_Ns3TypeIdAttributeInformation_methods(root_module, root_module['ns3::TypeId::AttributeInformation'])
     register_Ns3TypeIdTraceSourceInformation_methods(root_module, root_module['ns3::TypeId::TraceSourceInformation'])
     register_Ns3UniformVariable_methods(root_module, root_module['ns3::UniformVariable'])
+    register_Ns3Vector2D_methods(root_module, root_module['ns3::Vector2D'])
+    register_Ns3Vector3D_methods(root_module, root_module['ns3::Vector3D'])
     register_Ns3WeibullVariable_methods(root_module, root_module['ns3::WeibullVariable'])
     register_Ns3ZetaVariable_methods(root_module, root_module['ns3::ZetaVariable'])
     register_Ns3ZipfVariable_methods(root_module, root_module['ns3::ZipfVariable'])
@@ -231,6 +259,7 @@
     register_Ns3JakesPropagationLossModel_methods(root_module, root_module['ns3::JakesPropagationLossModel'])
     register_Ns3LogDistancePropagationLossModel_methods(root_module, root_module['ns3::LogDistancePropagationLossModel'])
     register_Ns3MatrixPropagationLossModel_methods(root_module, root_module['ns3::MatrixPropagationLossModel'])
+    register_Ns3MobilityModel_methods(root_module, root_module['ns3::MobilityModel'])
     register_Ns3NakagamiPropagationLossModel_methods(root_module, root_module['ns3::NakagamiPropagationLossModel'])
     register_Ns3RandomVariableChecker_methods(root_module, root_module['ns3::RandomVariableChecker'])
     register_Ns3RandomVariableValue_methods(root_module, root_module['ns3::RandomVariableValue'])
@@ -238,6 +267,10 @@
     register_Ns3TimeValue_methods(root_module, root_module['ns3::TimeValue'])
     register_Ns3TypeIdChecker_methods(root_module, root_module['ns3::TypeIdChecker'])
     register_Ns3TypeIdValue_methods(root_module, root_module['ns3::TypeIdValue'])
+    register_Ns3Vector2DChecker_methods(root_module, root_module['ns3::Vector2DChecker'])
+    register_Ns3Vector2DValue_methods(root_module, root_module['ns3::Vector2DValue'])
+    register_Ns3Vector3DChecker_methods(root_module, root_module['ns3::Vector3DChecker'])
+    register_Ns3Vector3DValue_methods(root_module, root_module['ns3::Vector3DValue'])
     return
 
 def register_Ns3AttributeConstructionList_methods(root_module, cls):
@@ -648,6 +681,36 @@
                    [param('double', 's'), param('double', 'l')])
     return
 
+def register_Ns3Vector2D_methods(root_module, cls):
+    cls.add_output_stream_operator()
+    ## vector.h (module 'core'): ns3::Vector2D::Vector2D(ns3::Vector2D const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::Vector2D const &', 'arg0')])
+    ## vector.h (module 'core'): ns3::Vector2D::Vector2D(double _x, double _y) [constructor]
+    cls.add_constructor([param('double', '_x'), param('double', '_y')])
+    ## vector.h (module 'core'): ns3::Vector2D::Vector2D() [constructor]
+    cls.add_constructor([])
+    ## vector.h (module 'core'): ns3::Vector2D::x [variable]
+    cls.add_instance_attribute('x', 'double', is_const=False)
+    ## vector.h (module 'core'): ns3::Vector2D::y [variable]
+    cls.add_instance_attribute('y', 'double', is_const=False)
+    return
+
+def register_Ns3Vector3D_methods(root_module, cls):
+    cls.add_output_stream_operator()
+    ## vector.h (module 'core'): ns3::Vector3D::Vector3D(ns3::Vector3D const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::Vector3D const &', 'arg0')])
+    ## vector.h (module 'core'): ns3::Vector3D::Vector3D(double _x, double _y, double _z) [constructor]
+    cls.add_constructor([param('double', '_x'), param('double', '_y'), param('double', '_z')])
+    ## vector.h (module 'core'): ns3::Vector3D::Vector3D() [constructor]
+    cls.add_constructor([])
+    ## vector.h (module 'core'): ns3::Vector3D::x [variable]
+    cls.add_instance_attribute('x', 'double', is_const=False)
+    ## vector.h (module 'core'): ns3::Vector3D::y [variable]
+    cls.add_instance_attribute('y', 'double', is_const=False)
+    ## vector.h (module 'core'): ns3::Vector3D::z [variable]
+    cls.add_instance_attribute('z', 'double', is_const=False)
+    return
+
 def register_Ns3WeibullVariable_methods(root_module, cls):
     ## random-variable.h (module 'core'): ns3::WeibullVariable::WeibullVariable(ns3::WeibullVariable const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::WeibullVariable const &', 'arg0')])
@@ -1789,6 +1852,62 @@
                    is_const=True, visibility='private', is_virtual=True)
     return
 
+def register_Ns3MobilityModel_methods(root_module, cls):
+    ## mobility-model.h (module 'mobility'): ns3::MobilityModel::MobilityModel(ns3::MobilityModel const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::MobilityModel const &', 'arg0')])
+    ## mobility-model.h (module 'mobility'): ns3::MobilityModel::MobilityModel() [constructor]
+    cls.add_constructor([])
+    ## mobility-model.h (module 'mobility'): double ns3::MobilityModel::GetDistanceFrom(ns3::Ptr<const ns3::MobilityModel> position) const [member function]
+    cls.add_method('GetDistanceFrom', 
+                   'double', 
+                   [param('ns3::Ptr< ns3::MobilityModel const >', 'position')], 
+                   is_const=True)
+    ## mobility-model.h (module 'mobility'): ns3::Vector ns3::MobilityModel::GetPosition() const [member function]
+    cls.add_method('GetPosition', 
+                   'ns3::Vector', 
+                   [], 
+                   is_const=True)
+    ## mobility-model.h (module 'mobility'): double ns3::MobilityModel::GetRelativeSpeed(ns3::Ptr<const ns3::MobilityModel> other) const [member function]
+    cls.add_method('GetRelativeSpeed', 
+                   'double', 
+                   [param('ns3::Ptr< ns3::MobilityModel const >', 'other')], 
+                   is_const=True)
+    ## mobility-model.h (module 'mobility'): static ns3::TypeId ns3::MobilityModel::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## mobility-model.h (module 'mobility'): ns3::Vector ns3::MobilityModel::GetVelocity() const [member function]
+    cls.add_method('GetVelocity', 
+                   'ns3::Vector', 
+                   [], 
+                   is_const=True)
+    ## mobility-model.h (module 'mobility'): void ns3::MobilityModel::SetPosition(ns3::Vector const & position) [member function]
+    cls.add_method('SetPosition', 
+                   'void', 
+                   [param('ns3::Vector const &', 'position')])
+    ## mobility-model.h (module 'mobility'): void ns3::MobilityModel::NotifyCourseChange() const [member function]
+    cls.add_method('NotifyCourseChange', 
+                   'void', 
+                   [], 
+                   is_const=True, visibility='protected')
+    ## mobility-model.h (module 'mobility'): ns3::Vector ns3::MobilityModel::DoGetPosition() const [member function]
+    cls.add_method('DoGetPosition', 
+                   'ns3::Vector', 
+                   [], 
+                   is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True)
+    ## mobility-model.h (module 'mobility'): ns3::Vector ns3::MobilityModel::DoGetVelocity() const [member function]
+    cls.add_method('DoGetVelocity', 
+                   'ns3::Vector', 
+                   [], 
+                   is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True)
+    ## mobility-model.h (module 'mobility'): void ns3::MobilityModel::DoSetPosition(ns3::Vector const & position) [member function]
+    cls.add_method('DoSetPosition', 
+                   'void', 
+                   [param('ns3::Vector const &', 'position')], 
+                   is_pure_virtual=True, visibility='private', is_virtual=True)
+    return
+
 def register_Ns3NakagamiPropagationLossModel_methods(root_module, cls):
     ## propagation-loss-model.h (module 'propagation'): static ns3::TypeId ns3::NakagamiPropagationLossModel::GetTypeId() [member function]
     cls.add_method('GetTypeId', 
@@ -1924,6 +2043,86 @@
                    [param('ns3::TypeId const &', 'value')])
     return
 
+def register_Ns3Vector2DChecker_methods(root_module, cls):
+    ## vector.h (module 'core'): ns3::Vector2DChecker::Vector2DChecker() [constructor]
+    cls.add_constructor([])
+    ## vector.h (module 'core'): ns3::Vector2DChecker::Vector2DChecker(ns3::Vector2DChecker const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::Vector2DChecker const &', 'arg0')])
+    return
+
+def register_Ns3Vector2DValue_methods(root_module, cls):
+    ## vector.h (module 'core'): ns3::Vector2DValue::Vector2DValue() [constructor]
+    cls.add_constructor([])
+    ## vector.h (module 'core'): ns3::Vector2DValue::Vector2DValue(ns3::Vector2DValue const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::Vector2DValue const &', 'arg0')])
+    ## vector.h (module 'core'): ns3::Vector2DValue::Vector2DValue(ns3::Vector2D const & value) [constructor]
+    cls.add_constructor([param('ns3::Vector2D const &', 'value')])
+    ## vector.h (module 'core'): ns3::Ptr<ns3::AttributeValue> ns3::Vector2DValue::Copy() const [member function]
+    cls.add_method('Copy', 
+                   'ns3::Ptr< ns3::AttributeValue >', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## vector.h (module 'core'): bool ns3::Vector2DValue::DeserializeFromString(std::string value, ns3::Ptr<ns3::AttributeChecker const> checker) [member function]
+    cls.add_method('DeserializeFromString', 
+                   'bool', 
+                   [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], 
+                   is_virtual=True)
+    ## vector.h (module 'core'): ns3::Vector2D ns3::Vector2DValue::Get() const [member function]
+    cls.add_method('Get', 
+                   'ns3::Vector2D', 
+                   [], 
+                   is_const=True)
+    ## vector.h (module 'core'): std::string ns3::Vector2DValue::SerializeToString(ns3::Ptr<ns3::AttributeChecker const> checker) const [member function]
+    cls.add_method('SerializeToString', 
+                   'std::string', 
+                   [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], 
+                   is_const=True, is_virtual=True)
+    ## vector.h (module 'core'): void ns3::Vector2DValue::Set(ns3::Vector2D const & value) [member function]
+    cls.add_method('Set', 
+                   'void', 
+                   [param('ns3::Vector2D const &', 'value')])
+    return
+
+def register_Ns3Vector3DChecker_methods(root_module, cls):
+    ## vector.h (module 'core'): ns3::Vector3DChecker::Vector3DChecker() [constructor]
+    cls.add_constructor([])
+    ## vector.h (module 'core'): ns3::Vector3DChecker::Vector3DChecker(ns3::Vector3DChecker const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::Vector3DChecker const &', 'arg0')])
+    return
+
+def register_Ns3Vector3DValue_methods(root_module, cls):
+    ## vector.h (module 'core'): ns3::Vector3DValue::Vector3DValue() [constructor]
+    cls.add_constructor([])
+    ## vector.h (module 'core'): ns3::Vector3DValue::Vector3DValue(ns3::Vector3DValue const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::Vector3DValue const &', 'arg0')])
+    ## vector.h (module 'core'): ns3::Vector3DValue::Vector3DValue(ns3::Vector3D const & value) [constructor]
+    cls.add_constructor([param('ns3::Vector3D const &', 'value')])
+    ## vector.h (module 'core'): ns3::Ptr<ns3::AttributeValue> ns3::Vector3DValue::Copy() const [member function]
+    cls.add_method('Copy', 
+                   'ns3::Ptr< ns3::AttributeValue >', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## vector.h (module 'core'): bool ns3::Vector3DValue::DeserializeFromString(std::string value, ns3::Ptr<ns3::AttributeChecker const> checker) [member function]
+    cls.add_method('DeserializeFromString', 
+                   'bool', 
+                   [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], 
+                   is_virtual=True)
+    ## vector.h (module 'core'): ns3::Vector3D ns3::Vector3DValue::Get() const [member function]
+    cls.add_method('Get', 
+                   'ns3::Vector3D', 
+                   [], 
+                   is_const=True)
+    ## vector.h (module 'core'): std::string ns3::Vector3DValue::SerializeToString(ns3::Ptr<ns3::AttributeChecker const> checker) const [member function]
+    cls.add_method('SerializeToString', 
+                   'std::string', 
+                   [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], 
+                   is_const=True, is_virtual=True)
+    ## vector.h (module 'core'): void ns3::Vector3DValue::Set(ns3::Vector3D const & value) [member function]
+    cls.add_method('Set', 
+                   'void', 
+                   [param('ns3::Vector3D const &', 'value')])
+    return
+
 def register_functions(root_module):
     module = root_module
     register_functions_ns3_FatalImpl(module.get_submodule('FatalImpl'), root_module)
--- a/src/propagation/bindings/modulegen__gcc_LP64.py	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/propagation/bindings/modulegen__gcc_LP64.py	Fri Dec 16 18:51:18 2011 +0100
@@ -50,6 +50,10 @@
     module.add_class('TraceSourceInformation', import_from_module='ns.core', outer_class=root_module['ns3::TypeId'])
     ## random-variable.h (module 'core'): ns3::UniformVariable [class]
     module.add_class('UniformVariable', import_from_module='ns.core', parent=root_module['ns3::RandomVariable'])
+    ## vector.h (module 'core'): ns3::Vector2D [class]
+    module.add_class('Vector2D', import_from_module='ns.core')
+    ## vector.h (module 'core'): ns3::Vector3D [class]
+    module.add_class('Vector3D', import_from_module='ns.core')
     ## random-variable.h (module 'core'): ns3::WeibullVariable [class]
     module.add_class('WeibullVariable', import_from_module='ns.core', parent=root_module['ns3::RandomVariable'])
     ## random-variable.h (module 'core'): ns3::ZetaVariable [class]
@@ -146,6 +150,8 @@
     module.add_class('LogDistancePropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
     ## propagation-loss-model.h (module 'propagation'): ns3::MatrixPropagationLossModel [class]
     module.add_class('MatrixPropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
+    ## mobility-model.h (module 'mobility'): ns3::MobilityModel [class]
+    module.add_class('MobilityModel', import_from_module='ns.mobility', parent=root_module['ns3::Object'])
     ## propagation-loss-model.h (module 'propagation'): ns3::NakagamiPropagationLossModel [class]
     module.add_class('NakagamiPropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
     ## random-variable.h (module 'core'): ns3::RandomVariableChecker [class]
@@ -160,6 +166,26 @@
     module.add_class('TypeIdChecker', import_from_module='ns.core', parent=root_module['ns3::AttributeChecker'])
     ## type-id.h (module 'core'): ns3::TypeIdValue [class]
     module.add_class('TypeIdValue', import_from_module='ns.core', parent=root_module['ns3::AttributeValue'])
+    ## vector.h (module 'core'): ns3::Vector2DChecker [class]
+    module.add_class('Vector2DChecker', import_from_module='ns.core', parent=root_module['ns3::AttributeChecker'])
+    ## vector.h (module 'core'): ns3::Vector2DValue [class]
+    module.add_class('Vector2DValue', import_from_module='ns.core', parent=root_module['ns3::AttributeValue'])
+    ## vector.h (module 'core'): ns3::Vector3DChecker [class]
+    module.add_class('Vector3DChecker', import_from_module='ns.core', parent=root_module['ns3::AttributeChecker'])
+    ## vector.h (module 'core'): ns3::Vector3DValue [class]
+    module.add_class('Vector3DValue', import_from_module='ns.core', parent=root_module['ns3::AttributeValue'])
+    typehandlers.add_type_alias('ns3::Vector3DValue', 'ns3::VectorValue')
+    typehandlers.add_type_alias('ns3::Vector3DValue*', 'ns3::VectorValue*')
+    typehandlers.add_type_alias('ns3::Vector3DValue&', 'ns3::VectorValue&')
+    module.add_typedef(root_module['ns3::Vector3DValue'], 'VectorValue')
+    typehandlers.add_type_alias('ns3::Vector3D', 'ns3::Vector')
+    typehandlers.add_type_alias('ns3::Vector3D*', 'ns3::Vector*')
+    typehandlers.add_type_alias('ns3::Vector3D&', 'ns3::Vector&')
+    module.add_typedef(root_module['ns3::Vector3D'], 'Vector')
+    typehandlers.add_type_alias('ns3::Vector3DChecker', 'ns3::VectorChecker')
+    typehandlers.add_type_alias('ns3::Vector3DChecker*', 'ns3::VectorChecker*')
+    typehandlers.add_type_alias('ns3::Vector3DChecker&', 'ns3::VectorChecker&')
+    module.add_typedef(root_module['ns3::Vector3DChecker'], 'VectorChecker')
     
     ## Register a nested module for the namespace FatalImpl
     
@@ -186,6 +212,8 @@
     register_Ns3TypeIdAttributeInformation_methods(root_module, root_module['ns3::TypeId::AttributeInformation'])
     register_Ns3TypeIdTraceSourceInformation_methods(root_module, root_module['ns3::TypeId::TraceSourceInformation'])
     register_Ns3UniformVariable_methods(root_module, root_module['ns3::UniformVariable'])
+    register_Ns3Vector2D_methods(root_module, root_module['ns3::Vector2D'])
+    register_Ns3Vector3D_methods(root_module, root_module['ns3::Vector3D'])
     register_Ns3WeibullVariable_methods(root_module, root_module['ns3::WeibullVariable'])
     register_Ns3ZetaVariable_methods(root_module, root_module['ns3::ZetaVariable'])
     register_Ns3ZipfVariable_methods(root_module, root_module['ns3::ZipfVariable'])
@@ -231,6 +259,7 @@
     register_Ns3JakesPropagationLossModel_methods(root_module, root_module['ns3::JakesPropagationLossModel'])
     register_Ns3LogDistancePropagationLossModel_methods(root_module, root_module['ns3::LogDistancePropagationLossModel'])
     register_Ns3MatrixPropagationLossModel_methods(root_module, root_module['ns3::MatrixPropagationLossModel'])
+    register_Ns3MobilityModel_methods(root_module, root_module['ns3::MobilityModel'])
     register_Ns3NakagamiPropagationLossModel_methods(root_module, root_module['ns3::NakagamiPropagationLossModel'])
     register_Ns3RandomVariableChecker_methods(root_module, root_module['ns3::RandomVariableChecker'])
     register_Ns3RandomVariableValue_methods(root_module, root_module['ns3::RandomVariableValue'])
@@ -238,6 +267,10 @@
     register_Ns3TimeValue_methods(root_module, root_module['ns3::TimeValue'])
     register_Ns3TypeIdChecker_methods(root_module, root_module['ns3::TypeIdChecker'])
     register_Ns3TypeIdValue_methods(root_module, root_module['ns3::TypeIdValue'])
+    register_Ns3Vector2DChecker_methods(root_module, root_module['ns3::Vector2DChecker'])
+    register_Ns3Vector2DValue_methods(root_module, root_module['ns3::Vector2DValue'])
+    register_Ns3Vector3DChecker_methods(root_module, root_module['ns3::Vector3DChecker'])
+    register_Ns3Vector3DValue_methods(root_module, root_module['ns3::Vector3DValue'])
     return
 
 def register_Ns3AttributeConstructionList_methods(root_module, cls):
@@ -648,6 +681,36 @@
                    [param('double', 's'), param('double', 'l')])
     return
 
+def register_Ns3Vector2D_methods(root_module, cls):
+    cls.add_output_stream_operator()
+    ## vector.h (module 'core'): ns3::Vector2D::Vector2D(ns3::Vector2D const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::Vector2D const &', 'arg0')])
+    ## vector.h (module 'core'): ns3::Vector2D::Vector2D(double _x, double _y) [constructor]
+    cls.add_constructor([param('double', '_x'), param('double', '_y')])
+    ## vector.h (module 'core'): ns3::Vector2D::Vector2D() [constructor]
+    cls.add_constructor([])
+    ## vector.h (module 'core'): ns3::Vector2D::x [variable]
+    cls.add_instance_attribute('x', 'double', is_const=False)
+    ## vector.h (module 'core'): ns3::Vector2D::y [variable]
+    cls.add_instance_attribute('y', 'double', is_const=False)
+    return
+
+def register_Ns3Vector3D_methods(root_module, cls):
+    cls.add_output_stream_operator()
+    ## vector.h (module 'core'): ns3::Vector3D::Vector3D(ns3::Vector3D const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::Vector3D const &', 'arg0')])
+    ## vector.h (module 'core'): ns3::Vector3D::Vector3D(double _x, double _y, double _z) [constructor]
+    cls.add_constructor([param('double', '_x'), param('double', '_y'), param('double', '_z')])
+    ## vector.h (module 'core'): ns3::Vector3D::Vector3D() [constructor]
+    cls.add_constructor([])
+    ## vector.h (module 'core'): ns3::Vector3D::x [variable]
+    cls.add_instance_attribute('x', 'double', is_const=False)
+    ## vector.h (module 'core'): ns3::Vector3D::y [variable]
+    cls.add_instance_attribute('y', 'double', is_const=False)
+    ## vector.h (module 'core'): ns3::Vector3D::z [variable]
+    cls.add_instance_attribute('z', 'double', is_const=False)
+    return
+
 def register_Ns3WeibullVariable_methods(root_module, cls):
     ## random-variable.h (module 'core'): ns3::WeibullVariable::WeibullVariable(ns3::WeibullVariable const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::WeibullVariable const &', 'arg0')])
@@ -1789,6 +1852,62 @@
                    is_const=True, visibility='private', is_virtual=True)
     return
 
+def register_Ns3MobilityModel_methods(root_module, cls):
+    ## mobility-model.h (module 'mobility'): ns3::MobilityModel::MobilityModel(ns3::MobilityModel const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::MobilityModel const &', 'arg0')])
+    ## mobility-model.h (module 'mobility'): ns3::MobilityModel::MobilityModel() [constructor]
+    cls.add_constructor([])
+    ## mobility-model.h (module 'mobility'): double ns3::MobilityModel::GetDistanceFrom(ns3::Ptr<const ns3::MobilityModel> position) const [member function]
+    cls.add_method('GetDistanceFrom', 
+                   'double', 
+                   [param('ns3::Ptr< ns3::MobilityModel const >', 'position')], 
+                   is_const=True)
+    ## mobility-model.h (module 'mobility'): ns3::Vector ns3::MobilityModel::GetPosition() const [member function]
+    cls.add_method('GetPosition', 
+                   'ns3::Vector', 
+                   [], 
+                   is_const=True)
+    ## mobility-model.h (module 'mobility'): double ns3::MobilityModel::GetRelativeSpeed(ns3::Ptr<const ns3::MobilityModel> other) const [member function]
+    cls.add_method('GetRelativeSpeed', 
+                   'double', 
+                   [param('ns3::Ptr< ns3::MobilityModel const >', 'other')], 
+                   is_const=True)
+    ## mobility-model.h (module 'mobility'): static ns3::TypeId ns3::MobilityModel::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## mobility-model.h (module 'mobility'): ns3::Vector ns3::MobilityModel::GetVelocity() const [member function]
+    cls.add_method('GetVelocity', 
+                   'ns3::Vector', 
+                   [], 
+                   is_const=True)
+    ## mobility-model.h (module 'mobility'): void ns3::MobilityModel::SetPosition(ns3::Vector const & position) [member function]
+    cls.add_method('SetPosition', 
+                   'void', 
+                   [param('ns3::Vector const &', 'position')])
+    ## mobility-model.h (module 'mobility'): void ns3::MobilityModel::NotifyCourseChange() const [member function]
+    cls.add_method('NotifyCourseChange', 
+                   'void', 
+                   [], 
+                   is_const=True, visibility='protected')
+    ## mobility-model.h (module 'mobility'): ns3::Vector ns3::MobilityModel::DoGetPosition() const [member function]
+    cls.add_method('DoGetPosition', 
+                   'ns3::Vector', 
+                   [], 
+                   is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True)
+    ## mobility-model.h (module 'mobility'): ns3::Vector ns3::MobilityModel::DoGetVelocity() const [member function]
+    cls.add_method('DoGetVelocity', 
+                   'ns3::Vector', 
+                   [], 
+                   is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True)
+    ## mobility-model.h (module 'mobility'): void ns3::MobilityModel::DoSetPosition(ns3::Vector const & position) [member function]
+    cls.add_method('DoSetPosition', 
+                   'void', 
+                   [param('ns3::Vector const &', 'position')], 
+                   is_pure_virtual=True, visibility='private', is_virtual=True)
+    return
+
 def register_Ns3NakagamiPropagationLossModel_methods(root_module, cls):
     ## propagation-loss-model.h (module 'propagation'): static ns3::TypeId ns3::NakagamiPropagationLossModel::GetTypeId() [member function]
     cls.add_method('GetTypeId', 
@@ -1924,6 +2043,86 @@
                    [param('ns3::TypeId const &', 'value')])
     return
 
+def register_Ns3Vector2DChecker_methods(root_module, cls):
+    ## vector.h (module 'core'): ns3::Vector2DChecker::Vector2DChecker() [constructor]
+    cls.add_constructor([])
+    ## vector.h (module 'core'): ns3::Vector2DChecker::Vector2DChecker(ns3::Vector2DChecker const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::Vector2DChecker const &', 'arg0')])
+    return
+
+def register_Ns3Vector2DValue_methods(root_module, cls):
+    ## vector.h (module 'core'): ns3::Vector2DValue::Vector2DValue() [constructor]
+    cls.add_constructor([])
+    ## vector.h (module 'core'): ns3::Vector2DValue::Vector2DValue(ns3::Vector2DValue const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::Vector2DValue const &', 'arg0')])
+    ## vector.h (module 'core'): ns3::Vector2DValue::Vector2DValue(ns3::Vector2D const & value) [constructor]
+    cls.add_constructor([param('ns3::Vector2D const &', 'value')])
+    ## vector.h (module 'core'): ns3::Ptr<ns3::AttributeValue> ns3::Vector2DValue::Copy() const [member function]
+    cls.add_method('Copy', 
+                   'ns3::Ptr< ns3::AttributeValue >', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## vector.h (module 'core'): bool ns3::Vector2DValue::DeserializeFromString(std::string value, ns3::Ptr<ns3::AttributeChecker const> checker) [member function]
+    cls.add_method('DeserializeFromString', 
+                   'bool', 
+                   [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], 
+                   is_virtual=True)
+    ## vector.h (module 'core'): ns3::Vector2D ns3::Vector2DValue::Get() const [member function]
+    cls.add_method('Get', 
+                   'ns3::Vector2D', 
+                   [], 
+                   is_const=True)
+    ## vector.h (module 'core'): std::string ns3::Vector2DValue::SerializeToString(ns3::Ptr<ns3::AttributeChecker const> checker) const [member function]
+    cls.add_method('SerializeToString', 
+                   'std::string', 
+                   [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], 
+                   is_const=True, is_virtual=True)
+    ## vector.h (module 'core'): void ns3::Vector2DValue::Set(ns3::Vector2D const & value) [member function]
+    cls.add_method('Set', 
+                   'void', 
+                   [param('ns3::Vector2D const &', 'value')])
+    return
+
+def register_Ns3Vector3DChecker_methods(root_module, cls):
+    ## vector.h (module 'core'): ns3::Vector3DChecker::Vector3DChecker() [constructor]
+    cls.add_constructor([])
+    ## vector.h (module 'core'): ns3::Vector3DChecker::Vector3DChecker(ns3::Vector3DChecker const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::Vector3DChecker const &', 'arg0')])
+    return
+
+def register_Ns3Vector3DValue_methods(root_module, cls):
+    ## vector.h (module 'core'): ns3::Vector3DValue::Vector3DValue() [constructor]
+    cls.add_constructor([])
+    ## vector.h (module 'core'): ns3::Vector3DValue::Vector3DValue(ns3::Vector3DValue const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::Vector3DValue const &', 'arg0')])
+    ## vector.h (module 'core'): ns3::Vector3DValue::Vector3DValue(ns3::Vector3D const & value) [constructor]
+    cls.add_constructor([param('ns3::Vector3D const &', 'value')])
+    ## vector.h (module 'core'): ns3::Ptr<ns3::AttributeValue> ns3::Vector3DValue::Copy() const [member function]
+    cls.add_method('Copy', 
+                   'ns3::Ptr< ns3::AttributeValue >', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## vector.h (module 'core'): bool ns3::Vector3DValue::DeserializeFromString(std::string value, ns3::Ptr<ns3::AttributeChecker const> checker) [member function]
+    cls.add_method('DeserializeFromString', 
+                   'bool', 
+                   [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], 
+                   is_virtual=True)
+    ## vector.h (module 'core'): ns3::Vector3D ns3::Vector3DValue::Get() const [member function]
+    cls.add_method('Get', 
+                   'ns3::Vector3D', 
+                   [], 
+                   is_const=True)
+    ## vector.h (module 'core'): std::string ns3::Vector3DValue::SerializeToString(ns3::Ptr<ns3::AttributeChecker const> checker) const [member function]
+    cls.add_method('SerializeToString', 
+                   'std::string', 
+                   [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], 
+                   is_const=True, is_virtual=True)
+    ## vector.h (module 'core'): void ns3::Vector3DValue::Set(ns3::Vector3D const & value) [member function]
+    cls.add_method('Set', 
+                   'void', 
+                   [param('ns3::Vector3D const &', 'value')])
+    return
+
 def register_functions(root_module):
     module = root_module
     register_functions_ns3_FatalImpl(module.get_submodule('FatalImpl'), root_module)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/propagation/bindings/modulegen_customizations.py	Fri Dec 16 18:51:18 2011 +0100
@@ -0,0 +1,5 @@
+
+def post_register_types(root_module):
+    root_module.add_include('"ns3/mobility-model.h"')
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/propagation/bindings/scan-header.h	Fri Dec 16 18:51:18 2011 +0100
@@ -0,0 +1,2 @@
+#include "ns3/mobility-model.h"
+#include "ns3/propagation-module.h"
--- a/src/propagation/model/propagation-loss-model.h	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/propagation/model/propagation-loss-model.h	Fri Dec 16 18:51:18 2011 +0100
@@ -56,7 +56,7 @@
 
   /**
    * \brief Enables a chain of loss models to act on the signal
-   * \param The next PropagationLossModel to add to the chain
+   * \param next The next PropagationLossModel to add to the chain
    *
    * This method of chaining propagation loss models only works commutatively
    * if the propagation loss of all models in the chain are independent
@@ -516,8 +516,8 @@
    * \brief Set loss (in dB, positive) between pair of ns-3 objects
    * (typically, nodes).
    * 
-   * \param ma          Source mobility model
-   * \param mb          Destination mobility model
+   * \param a ma          Source mobility model
+   * \param b mb          Destination mobility model
    * \param loss        a -> b path loss, positive in dB
    * \param symmetric   If true (default), both a->b and b->a paths will be affected
    */ 
--- a/src/spectrum/bindings/modulegen__gcc_ILP32.py	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/spectrum/bindings/modulegen__gcc_ILP32.py	Fri Dec 16 18:51:18 2011 +0100
@@ -3495,6 +3495,10 @@
     cls.add_constructor([param('ns3::SpectrumInterference const &', 'arg0')])
     ## spectrum-interference.h (module 'spectrum'): ns3::SpectrumInterference::SpectrumInterference() [constructor]
     cls.add_constructor([])
+    ## spectrum-interference.h (module 'spectrum'): void ns3::SpectrumInterference::AbortRx() [member function]
+    cls.add_method('AbortRx', 
+                   'void', 
+                   [])
     ## spectrum-interference.h (module 'spectrum'): void ns3::SpectrumInterference::AddSignal(ns3::Ptr<ns3::SpectrumValue const> spd, ns3::Time const duration) [member function]
     cls.add_method('AddSignal', 
                    'void', 
@@ -4876,6 +4880,11 @@
                    'ns3::Vector', 
                    [], 
                    is_const=True)
+    ## mobility-model.h (module 'mobility'): double ns3::MobilityModel::GetRelativeSpeed(ns3::Ptr<const ns3::MobilityModel> other) const [member function]
+    cls.add_method('GetRelativeSpeed', 
+                   'double', 
+                   [param('ns3::Ptr< ns3::MobilityModel const >', 'other')], 
+                   is_const=True)
     ## mobility-model.h (module 'mobility'): static ns3::TypeId ns3::MobilityModel::GetTypeId() [member function]
     cls.add_method('GetTypeId', 
                    'ns3::TypeId', 
@@ -6248,14 +6257,14 @@
     module.add_function('Norm', 
                         'double', 
                         [param('ns3::SpectrumValue const &', 'x')])
-    ## spectrum-value.h (module 'spectrum'): extern ns3::SpectrumValue ns3::Pow(ns3::SpectrumValue const & base, double exp) [free function]
+    ## spectrum-value.h (module 'spectrum'): extern ns3::SpectrumValue ns3::Pow(ns3::SpectrumValue const & lhs, double rhs) [free function]
     module.add_function('Pow', 
                         'ns3::SpectrumValue', 
-                        [param('ns3::SpectrumValue const &', 'base'), param('double', 'exp')])
-    ## spectrum-value.h (module 'spectrum'): extern ns3::SpectrumValue ns3::Pow(double base, ns3::SpectrumValue const & exp) [free function]
+                        [param('ns3::SpectrumValue const &', 'lhs'), param('double', 'rhs')])
+    ## spectrum-value.h (module 'spectrum'): extern ns3::SpectrumValue ns3::Pow(double lhs, ns3::SpectrumValue const & rhs) [free function]
     module.add_function('Pow', 
                         'ns3::SpectrumValue', 
-                        [param('double', 'base'), param('ns3::SpectrumValue const &', 'exp')])
+                        [param('double', 'lhs'), param('ns3::SpectrumValue const &', 'rhs')])
     ## spectrum-value.h (module 'spectrum'): extern double ns3::Prod(ns3::SpectrumValue const & x) [free function]
     module.add_function('Prod', 
                         'double', 
--- a/src/spectrum/bindings/modulegen__gcc_LP64.py	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/spectrum/bindings/modulegen__gcc_LP64.py	Fri Dec 16 18:51:18 2011 +0100
@@ -3495,6 +3495,10 @@
     cls.add_constructor([param('ns3::SpectrumInterference const &', 'arg0')])
     ## spectrum-interference.h (module 'spectrum'): ns3::SpectrumInterference::SpectrumInterference() [constructor]
     cls.add_constructor([])
+    ## spectrum-interference.h (module 'spectrum'): void ns3::SpectrumInterference::AbortRx() [member function]
+    cls.add_method('AbortRx', 
+                   'void', 
+                   [])
     ## spectrum-interference.h (module 'spectrum'): void ns3::SpectrumInterference::AddSignal(ns3::Ptr<ns3::SpectrumValue const> spd, ns3::Time const duration) [member function]
     cls.add_method('AddSignal', 
                    'void', 
@@ -4876,6 +4880,11 @@
                    'ns3::Vector', 
                    [], 
                    is_const=True)
+    ## mobility-model.h (module 'mobility'): double ns3::MobilityModel::GetRelativeSpeed(ns3::Ptr<const ns3::MobilityModel> other) const [member function]
+    cls.add_method('GetRelativeSpeed', 
+                   'double', 
+                   [param('ns3::Ptr< ns3::MobilityModel const >', 'other')], 
+                   is_const=True)
     ## mobility-model.h (module 'mobility'): static ns3::TypeId ns3::MobilityModel::GetTypeId() [member function]
     cls.add_method('GetTypeId', 
                    'ns3::TypeId', 
@@ -6248,14 +6257,14 @@
     module.add_function('Norm', 
                         'double', 
                         [param('ns3::SpectrumValue const &', 'x')])
-    ## spectrum-value.h (module 'spectrum'): extern ns3::SpectrumValue ns3::Pow(ns3::SpectrumValue const & base, double exp) [free function]
+    ## spectrum-value.h (module 'spectrum'): extern ns3::SpectrumValue ns3::Pow(ns3::SpectrumValue const & lhs, double rhs) [free function]
     module.add_function('Pow', 
                         'ns3::SpectrumValue', 
-                        [param('ns3::SpectrumValue const &', 'base'), param('double', 'exp')])
-    ## spectrum-value.h (module 'spectrum'): extern ns3::SpectrumValue ns3::Pow(double base, ns3::SpectrumValue const & exp) [free function]
+                        [param('ns3::SpectrumValue const &', 'lhs'), param('double', 'rhs')])
+    ## spectrum-value.h (module 'spectrum'): extern ns3::SpectrumValue ns3::Pow(double lhs, ns3::SpectrumValue const & rhs) [free function]
     module.add_function('Pow', 
                         'ns3::SpectrumValue', 
-                        [param('double', 'base'), param('ns3::SpectrumValue const &', 'exp')])
+                        [param('double', 'lhs'), param('ns3::SpectrumValue const &', 'rhs')])
     ## spectrum-value.h (module 'spectrum'): extern double ns3::Prod(ns3::SpectrumValue const & x) [free function]
     module.add_function('Prod', 
                         'double', 
--- a/src/spectrum/helper/adhoc-aloha-noack-ideal-phy-helper.h	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/spectrum/helper/adhoc-aloha-noack-ideal-phy-helper.h	Fri Dec 16 18:51:18 2011 +0100
@@ -37,11 +37,7 @@
 
 /**
  * \ingroup spectrum
- *
- *
- * create the NetDevice depicted in the figure
- * @image html HdOfdmAlohaNoAck.png
- *
+ * \brief create the AlohaNoackNetDevice
  */
 class AdhocAlohaNoackIdealPhyHelper
 {
--- a/src/spectrum/model/spectrum-value.h	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/spectrum/model/spectrum-value.h	Fri Dec 16 18:51:18 2011 +0100
@@ -434,23 +434,23 @@
   /**
    *
    *
-   * @param base the base
-   * @param exp  the exponent
+   * @param lhs the base
+   * @param rhs the exponent
    *
    * @return each value in base raised to the exponent
    */
-  friend SpectrumValue Pow (const SpectrumValue& base, double exp);
+  friend SpectrumValue Pow (const SpectrumValue& lhs, double rhs);
 
 
   /**
    *
    *
-   * @param base the base
-   * @param exp  the exponent
+   * @param lhs the base
+   * @param rhs the exponent
    *
    * @return the value in base raised to each value in the exponent
    */
-  friend SpectrumValue Pow (double base, const SpectrumValue& exp);
+  friend SpectrumValue Pow (double lhs, const SpectrumValue& rhs);
 
   /**
    *
@@ -535,15 +535,14 @@
 double Norm (const SpectrumValue& x);
 double Sum (const SpectrumValue& x);
 double Prod (const SpectrumValue& x);
-SpectrumValue Pow (const SpectrumValue& base, double exp);
-SpectrumValue Pow (double base, const SpectrumValue& exp);
-SpectrumValue Log10 (const SpectrumValue&  arg);
-SpectrumValue Log2 (const SpectrumValue&  arg);
-SpectrumValue Log (const SpectrumValue&  arg);
+SpectrumValue Pow (const SpectrumValue& lhs, double rhs);
+SpectrumValue Pow (double lhs, const SpectrumValue& rhs);
+SpectrumValue Log10 (const SpectrumValue& arg);
+SpectrumValue Log2 (const SpectrumValue& arg);
+SpectrumValue Log (const SpectrumValue& arg);
 double Integral (const SpectrumValue& x);
 
 
 } // namespace ns3
 
-
 #endif /* SPECTRUM_VALUE_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/test/ns3tcp/ns3tcp-no-delay-test-suite.cc	Fri Dec 16 18:51:18 2011 +0100
@@ -0,0 +1,206 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "ns3/log.h"
+#include "ns3/abort.h"
+#include "ns3/test.h"
+#include "ns3/pcap-file.h"
+#include "ns3/config.h"
+#include "ns3/string.h"
+#include "ns3/uinteger.h"
+#include "ns3/boolean.h"
+#include "ns3/data-rate.h"
+#include "ns3/inet-socket-address.h"
+#include "ns3/point-to-point-helper.h"
+#include "ns3/csma-helper.h"
+#include "ns3/internet-stack-helper.h"
+#include "ns3/ipv4-global-routing-helper.h"
+#include "ns3/ipv4-address-helper.h"
+#include "ns3/packet-sink-helper.h"
+#include "ns3/tcp-socket-factory.h"
+#include "ns3/node-container.h"
+#include "ns3/simulator.h"
+#include "ns3tcp-socket-writer.h"
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("Ns3TcpNoDelayTest");
+
+// ===========================================================================
+// Tests of Nagle's algorithm and the TCP no delay option
+// ===========================================================================
+//
+//
+class Ns3TcpNoDelayTestCase : public TestCase
+{
+public:
+  Ns3TcpNoDelayTestCase (bool noDelay);
+  virtual ~Ns3TcpNoDelayTestCase () {}
+
+private:
+  virtual void DoRun (void);
+  bool m_noDelay;
+  bool m_writeResults;
+
+  void SinkRx (std::string path, Ptr<const Packet> p, const Address &address);
+
+  TestVectors<uint32_t> m_inputs;
+  TestVectors<uint32_t> m_responses;
+};
+
+Ns3TcpNoDelayTestCase::Ns3TcpNoDelayTestCase (bool noDelay)
+  : TestCase ("Check that ns-3 TCP Nagle's algorithm works correctly and that we can turn it off."),
+    m_noDelay (noDelay),
+    m_writeResults (false)
+{
+}
+
+void 
+Ns3TcpNoDelayTestCase::SinkRx (std::string path, Ptr<const Packet> p, const Address &address)
+{
+  m_responses.Add (p->GetSize ());
+}
+
+void
+Ns3TcpNoDelayTestCase::DoRun (void)
+{
+  uint16_t sinkPort = 50000;
+  double sinkStopTime = 8;  // sec; will trigger Socket::Close
+  double writerStopTime = 5;  // sec; will trigger Socket::Close
+  double simStopTime = 10;  // sec
+  Time sinkStopTimeObj = Seconds (sinkStopTime);
+  Time writerStopTimeObj = Seconds (writerStopTime);
+  Time simStopTimeObj= Seconds (simStopTime);
+
+  Ptr<Node> n0 = CreateObject<Node> ();
+  Ptr<Node> n1 = CreateObject<Node> ();
+
+  PointToPointHelper pointToPoint;
+  pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
+  pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
+
+  NetDeviceContainer devices;
+  devices = pointToPoint.Install (n0, n1);
+
+  InternetStackHelper internet;
+  internet.InstallAll ();
+
+  Ipv4AddressHelper address;
+  address.SetBase ("10.1.1.0", "255.255.255.252");
+  Ipv4InterfaceContainer ifContainer = address.Assign (devices);
+
+  Ptr<SocketWriter> socketWriter = CreateObject<SocketWriter> ();
+  Address sinkAddress (InetSocketAddress (ifContainer.GetAddress (1), sinkPort));
+  socketWriter->Setup (n0, sinkAddress);
+  n0->AddApplication (socketWriter);
+  socketWriter->SetStartTime (Seconds (0.));
+  socketWriter->SetStopTime (writerStopTimeObj);
+
+  PacketSinkHelper sink ("ns3::TcpSocketFactory",
+                         InetSocketAddress (Ipv4Address::GetAny (), sinkPort));
+  ApplicationContainer apps = sink.Install (n1);
+  // Start the sink application at time zero, and stop it at sinkStopTime
+  apps.Start (Seconds (0.0));
+  apps.Stop (sinkStopTimeObj);
+
+  Config::Connect ("/NodeList/*/ApplicationList/*/$ns3::PacketSink/Rx",
+                   MakeCallback (&Ns3TcpNoDelayTestCase::SinkRx, this));
+
+  // Enable or disable TCP no delay option
+  Config::SetDefault ("ns3::TcpSocket::TcpNoDelay", BooleanValue (m_noDelay));
+
+  // Connect the socket writer
+  Simulator::Schedule (Seconds (1), &SocketWriter::Connect, socketWriter);
+
+  // Write 5 packets to get some bytes in flight and some acks going
+  Simulator::Schedule (Seconds (2), &SocketWriter::Write, socketWriter, 2680);
+  m_inputs.Add (536);
+  m_inputs.Add (536);
+  m_inputs.Add (536);
+  m_inputs.Add (536);
+  m_inputs.Add (536);
+
+  // Write one byte after 10 ms to ensure that some data is outstanding 
+  // and the window is big enough
+  Simulator::Schedule (Seconds (2.010), &SocketWriter::Write, socketWriter, 1);
+
+  // If Nagle is not enabled, i.e. no delay is on, add an input for a 1-byte 
+  // packet to be received
+  if (m_noDelay)
+    {
+      m_inputs.Add (1);
+    }
+
+  // One ms later, write 535 bytes, i.e. one segment size - 1
+  Simulator::Schedule (Seconds (2.012), &SocketWriter::Write, socketWriter, 535);
+
+  // If Nagle is not enabled, add an input for a 535 byte packet,
+  // otherwise, we should get a single "full" packet of 536 bytes
+  if (m_noDelay)
+    {
+      m_inputs.Add (535);
+    }
+  else
+    {
+      m_inputs.Add (536);
+    }
+
+  // Close down the socket
+  Simulator::Schedule (writerStopTimeObj, &SocketWriter::Close, socketWriter);
+
+  if (m_writeResults)
+    {
+      std::ostringstream oss;
+      if (m_noDelay)
+        {
+          oss << "tcp-no-delay-on-test-case";
+          pointToPoint.EnablePcapAll (oss.str ());
+        }
+      else
+        {
+          oss << "tcp-no-delay-off-test-case";
+          pointToPoint.EnablePcapAll (oss.str ());
+        }
+    }
+
+  Simulator::Stop (simStopTimeObj);
+  Simulator::Run ();
+  Simulator::Destroy ();
+
+  // Compare inputs and outputs
+  NS_TEST_ASSERT_MSG_EQ (m_inputs.GetN (), m_responses.GetN (), "Incorrect number of expected receive events");
+  for (uint32_t i = 0; i < m_responses.GetN (); i++)
+    {
+      uint32_t in = m_inputs.Get (i);
+      uint32_t out = m_responses.Get (i);
+      NS_TEST_ASSERT_MSG_EQ (in, out, "Mismatch:  expected " << in << " bytes, got " << out << " bytes");
+    }
+}
+
+class Ns3TcpNoDelayTestSuite : public TestSuite
+{
+public:
+  Ns3TcpNoDelayTestSuite ();
+};
+
+Ns3TcpNoDelayTestSuite::Ns3TcpNoDelayTestSuite ()
+  : TestSuite ("ns3-tcp-no-delay", SYSTEM)
+{
+  AddTestCase (new Ns3TcpNoDelayTestCase (true));
+  AddTestCase (new Ns3TcpNoDelayTestCase (false));
+}
+
+static Ns3TcpNoDelayTestSuite ns3TcpNoDelayTestSuite;
--- a/src/test/ns3tcp/trTidy.pl	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/test/ns3tcp/trTidy.pl	Fri Dec 16 18:51:18 2011 +0100
@@ -1,3 +1,4 @@
+#!/usr/bin/perl
 ###
 # *
 # * Copyright (c) 2010 Adrian Sai-wah Tam
--- a/src/test/ns3tcp/wscript	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/test/ns3tcp/wscript	Fri Dec 16 18:51:18 2011 +0100
@@ -28,6 +28,7 @@
         'ns3tcp-socket-test-suite.cc',
         'ns3tcp-loss-test-suite.cc',
         'ns3tcp-state-test-suite.cc',
+        'ns3tcp-no-delay-test-suite.cc',
         ]
 
     if bld.env['NSC_ENABLED']:
--- a/src/topology-read/bindings/modulegen__gcc_ILP32.py	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/topology-read/bindings/modulegen__gcc_ILP32.py	Fri Dec 16 18:51:18 2011 +0100
@@ -1591,14 +1591,16 @@
     cls.add_method('AttributesEnd', 
                    'std::_Rb_tree_const_iterator< std::pair< std::basic_string< char, std::char_traits< char >, std::allocator< char > > const, std::basic_string< char, std::char_traits< char >, std::allocator< char > > > >', 
                    [])
-    ## topology-reader.h (module 'topology-read'): std::string ns3::TopologyReader::Link::GetAttribute(std::string name) [member function]
+    ## topology-reader.h (module 'topology-read'): std::string ns3::TopologyReader::Link::GetAttribute(std::string name) const [member function]
     cls.add_method('GetAttribute', 
                    'std::string', 
-                   [param('std::string', 'name')])
-    ## topology-reader.h (module 'topology-read'): bool ns3::TopologyReader::Link::GetAttributeFailSafe(std::string name, std::string & value) [member function]
+                   [param('std::string', 'name')], 
+                   is_const=True)
+    ## topology-reader.h (module 'topology-read'): bool ns3::TopologyReader::Link::GetAttributeFailSafe(std::string name, std::string & value) const [member function]
     cls.add_method('GetAttributeFailSafe', 
                    'bool', 
-                   [param('std::string', 'name'), param('std::string &', 'value')])
+                   [param('std::string', 'name'), param('std::string &', 'value')], 
+                   is_const=True)
     ## topology-reader.h (module 'topology-read'): ns3::Ptr<ns3::Node> ns3::TopologyReader::Link::GetFromNode() const [member function]
     cls.add_method('GetFromNode', 
                    'ns3::Ptr< ns3::Node >', 
--- a/src/topology-read/bindings/modulegen__gcc_LP64.py	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/topology-read/bindings/modulegen__gcc_LP64.py	Fri Dec 16 18:51:18 2011 +0100
@@ -1591,14 +1591,16 @@
     cls.add_method('AttributesEnd', 
                    'std::_Rb_tree_const_iterator< std::pair< std::basic_string< char, std::char_traits< char >, std::allocator< char > > const, std::basic_string< char, std::char_traits< char >, std::allocator< char > > > >', 
                    [])
-    ## topology-reader.h (module 'topology-read'): std::string ns3::TopologyReader::Link::GetAttribute(std::string name) [member function]
+    ## topology-reader.h (module 'topology-read'): std::string ns3::TopologyReader::Link::GetAttribute(std::string name) const [member function]
     cls.add_method('GetAttribute', 
                    'std::string', 
-                   [param('std::string', 'name')])
-    ## topology-reader.h (module 'topology-read'): bool ns3::TopologyReader::Link::GetAttributeFailSafe(std::string name, std::string & value) [member function]
+                   [param('std::string', 'name')], 
+                   is_const=True)
+    ## topology-reader.h (module 'topology-read'): bool ns3::TopologyReader::Link::GetAttributeFailSafe(std::string name, std::string & value) const [member function]
     cls.add_method('GetAttributeFailSafe', 
                    'bool', 
-                   [param('std::string', 'name'), param('std::string &', 'value')])
+                   [param('std::string', 'name'), param('std::string &', 'value')], 
+                   is_const=True)
     ## topology-reader.h (module 'topology-read'): ns3::Ptr<ns3::Node> ns3::TopologyReader::Link::GetFromNode() const [member function]
     cls.add_method('GetFromNode', 
                    'ns3::Ptr< ns3::Node >', 
--- a/src/topology-read/model/topology-reader.cc	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/topology-read/model/topology-reader.cc	Fri Dec 16 18:51:18 2011 +0100
@@ -49,7 +49,7 @@
 }
 
 void
-TopologyReader::SetFileName (const std::string fileName)
+TopologyReader::SetFileName (const std::string &fileName)
 {
   m_fileName = fileName;
 }
@@ -94,7 +94,7 @@
 }
 
 
-TopologyReader::Link::Link ( Ptr<Node> fromPtr, std::string fromName, Ptr<Node> toPtr, std::string toName )
+TopologyReader::Link::Link ( Ptr<Node> fromPtr, const std::string &fromName, Ptr<Node> toPtr, const std::string &toName )
 {
   m_fromPtr = fromPtr;
   m_fromName = fromName;
@@ -131,14 +131,14 @@
 }
 
 std::string
-TopologyReader::Link::GetAttribute (std::string name) const
+TopologyReader::Link::GetAttribute (const std::string &name) const
 {
-  NS_ASSERT_MSG (m_linkAttr.find (name) == m_linkAttr.end (), "Requested topology link attribute not found");
+  NS_ASSERT_MSG (m_linkAttr.find (name) != m_linkAttr.end (), "Requested topology link attribute not found");
   return m_linkAttr.find (name)->second;
 }
 
 bool
-TopologyReader::Link::GetAttributeFailSafe (std::string name, std::string &value) const
+TopologyReader::Link::GetAttributeFailSafe (const std::string &name, std::string &value) const
 {
   if ( m_linkAttr.find (name) == m_linkAttr.end () )
     {
@@ -149,7 +149,7 @@
 }
 
 void
-TopologyReader::Link::SetAttribute (std::string name, std::string &value)
+TopologyReader::Link::SetAttribute (const std::string &name, const std::string &value)
 {
   m_linkAttr[name] = value;
 }
--- a/src/topology-read/model/topology-reader.h	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/topology-read/model/topology-reader.h	Fri Dec 16 18:51:18 2011 +0100
@@ -57,7 +57,7 @@
   /**
    * \brief Constant iterator to scan the map of link attributes.
    */
-    typedef std::map<std::string, std::string >::const_iterator ConstAttributesIterator;
+    typedef std::map<std::string, std::string>::const_iterator ConstAttributesIterator;
 
     /**
      * \brief Constructor
@@ -66,7 +66,7 @@
      * \param toPtr Ptr to the node the link is directed to
      * \param toName name of the node the link is directed to
      */
-    Link ( Ptr<Node> fromPtr, std::string fromName, Ptr<Node> toPtr, std::string toName );
+    Link ( Ptr<Node> fromPtr, const std::string &fromName, Ptr<Node> toPtr, const std::string &toName );
 
     /**
      * \brief Returns a Ptr<Node> to the "from" node of the link
@@ -95,7 +95,7 @@
      *
      * \return the value of the attribute
      */
-    std::string GetAttribute (std::string name) const;
+    std::string GetAttribute (const std::string &name) const;
     /**
      * \brief Returns the value of a link attribute.
      * \param name the name of the attribute
@@ -103,13 +103,13 @@
      *
      * \return true if the attribute was defined, false otherwise.
      */
-    bool GetAttributeFailSafe (std::string name, std::string &value) const;
+    bool GetAttributeFailSafe (const std::string &name, std::string &value) const;
     /**
      * \brief Sets an arbitrary link attribute.
      * \param name the name of the attribute
      * \param value the value of the attribute
      */
-    void SetAttribute (std::string name, std::string &value);
+    void SetAttribute (const std::string &name, const std::string &value);
     /**
      * \brief Returns an iterator to the begin of the attributes.
      * \return a const iterator to the first attribute of a link.
@@ -127,7 +127,7 @@
     Ptr< Node > m_fromPtr;
     std::string m_toName;
     Ptr< Node > m_toPtr;
-    std::map<std::string, std::string > m_linkAttr;
+    std::map<std::string, std::string> m_linkAttr;
   };
 
   /**
@@ -157,7 +157,7 @@
    * \brief Sets the input file name.
    * \param fileName the input file name.
    */
-  void SetFileName (const std::string fileName);
+  void SetFileName (const std::string &fileName);
 
   /**
    * \brief Returns the input file name.
--- a/src/uan/bindings/modulegen__gcc_ILP32.py	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/uan/bindings/modulegen__gcc_ILP32.py	Fri Dec 16 18:51:18 2011 +0100
@@ -6010,6 +6010,11 @@
                    'ns3::Vector', 
                    [], 
                    is_const=True)
+    ## mobility-model.h (module 'mobility'): double ns3::MobilityModel::GetRelativeSpeed(ns3::Ptr<const ns3::MobilityModel> other) const [member function]
+    cls.add_method('GetRelativeSpeed', 
+                   'double', 
+                   [param('ns3::Ptr< ns3::MobilityModel const >', 'other')], 
+                   is_const=True)
     ## mobility-model.h (module 'mobility'): static ns3::TypeId ns3::MobilityModel::GetTypeId() [member function]
     cls.add_method('GetTypeId', 
                    'ns3::TypeId', 
--- a/src/uan/bindings/modulegen__gcc_LP64.py	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/uan/bindings/modulegen__gcc_LP64.py	Fri Dec 16 18:51:18 2011 +0100
@@ -6010,6 +6010,11 @@
                    'ns3::Vector', 
                    [], 
                    is_const=True)
+    ## mobility-model.h (module 'mobility'): double ns3::MobilityModel::GetRelativeSpeed(ns3::Ptr<const ns3::MobilityModel> other) const [member function]
+    cls.add_method('GetRelativeSpeed', 
+                   'double', 
+                   [param('ns3::Ptr< ns3::MobilityModel const >', 'other')], 
+                   is_const=True)
     ## mobility-model.h (module 'mobility'): static ns3::TypeId ns3::MobilityModel::GetTypeId() [member function]
     cls.add_method('GetTypeId', 
                    'ns3::TypeId', 
--- a/src/uan/helper/uan-helper.h	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/uan/helper/uan-helper.h	Fri Dec 16 18:51:18 2011 +0100
@@ -1,10 +1,9 @@
 /*
  * Copyright (c) 2008 University of Washington
  *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -12,7 +11,8 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Author: Leonard Tracy <lentracy@u.washington.edu>
  */
@@ -188,8 +188,8 @@
 
   NetDeviceContainer Install (NodeContainer c) const;
   /**
+   * \param c a set of nodes
    * \param channel a channel to use
-   * \param c a set of nodes
    *
    * For each of the input nodes, a new ns3::UanNetDevice is attached
    * to the shared input channel. Each ns3::UanNetDevice is also
@@ -202,6 +202,7 @@
 
   /**
    * \param node a node where to install the uan components
+   * \param channel a channel to use
    *
    * Create a default uan stack with:
    * - default channel, ideal propagation and default noise model
--- a/src/uan/model/uan-phy.h	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/uan/model/uan-phy.h	Fri Dec 16 18:51:18 2011 +0100
@@ -169,7 +169,7 @@
 public:
   static TypeId GetTypeId (void);
 
-  // / Enum defining possible Phy states
+  /// Enum defining possible Phy states
   enum State
   {
     IDLE, CCABUSY, RX, TX, SLEEP
--- a/src/uan/model/uan-tx-mode.h	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/uan/model/uan-tx-mode.h	Fri Dec 16 18:51:18 2011 +0100
@@ -200,7 +200,7 @@
  */
 std::istream &operator >> (std::istream &is, UanModesList &ml);
 
-///UanModesList is attribute value
+/// UanModesList is attribute value
 ATTRIBUTE_HELPER_HEADER (UanModesList);
 
 } // namespace ns3
--- a/src/wifi/model/interference-helper.h	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/wifi/model/interference-helper.h	Fri Dec 16 18:51:18 2011 +0100
@@ -121,7 +121,7 @@
 
   double m_noiseFigure; /**< noise figure (linear) */
   Ptr<ErrorRateModel> m_errorRateModel;
-  ///Experimental: needed for energy duration calculation
+  /// Experimental: needed for energy duration calculation
   NiChanges m_niChanges;
   double m_firstPower;
   bool m_rxing;
--- a/src/wifi/model/wifi-information-element-vector.h	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/wifi/model/wifi-information-element-vector.h	Fri Dec 16 18:51:18 2011 +0100
@@ -46,7 +46,7 @@
   WifiInformationElementVector ();
   ~WifiInformationElementVector ();
   ///\name Inherited from Header
-  //\{
+  // \{
   static TypeId GetTypeId ();
   TypeId GetInstanceTypeId () const;
   virtual uint32_t GetSerializedSize () const;
--- a/src/wifi/model/wifi-phy.h	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/wifi/model/wifi-phy.h	Fri Dec 16 18:51:18 2011 +0100
@@ -252,11 +252,9 @@
    */
   static WifiMode GetPlcpHeaderMode (WifiMode payloadMode, WifiPreamble preamble);
 
-  /** 
-   * 
-   * 
+  /**
    * \param payloadMode the WifiMode use for the transmission of the payload
-   * \param preamble the type of preamble 
+   * \param preamble the type of preamble
    * 
    * \return the duration of the PLCP header in microseconds
    */
@@ -271,8 +269,8 @@
   static uint32_t GetPlcpPreambleDurationMicroSeconds (WifiMode payloadMode, WifiPreamble preamble);
 
   /** 
+   * \param size the number of bytes in the packet to send
    * \param payloadMode the WifiMode use for the transmission of the payload
-   * \param preamble the type of preamble 
    * 
    * \return the duration of the payload in microseconds
    */
--- a/src/wifi/model/wifi-remote-station-manager.h	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/wifi/model/wifi-remote-station-manager.h	Fri Dec 16 18:51:18 2011 +0100
@@ -64,17 +64,17 @@
    * because it resets time of last update.
    */
   double CalculateAveragingCoefficient ();
-  ///averaging coefficient depends on the memory time
+  /// averaging coefficient depends on the memory time
   Time m_memoryTime;
-  ///when last update has occured
+  /// when last update has occured
   Time m_lastUpdate;
   /// moving percentage of failed frames
   double m_failAvg;
 };
 
 /**
+ * \ingroup wifi
  * \brief hold a list of per-remote-station state.
- * \ingroup wifi
  *
  * \sa ns3::WifiRemoteStation.
  */
--- a/src/wimax/model/bs-scheduler-rtps.cc	Fri Dec 16 18:50:05 2011 +0100
+++ b/src/wimax/model/bs-scheduler-rtps.cc	Fri Dec 16 18:51:18 2011 +0100
@@ -110,23 +110,23 @@
   m_downlinkBursts->push_back (std::make_pair (dlMapIe, burst));
 }
 
+/**
+ * \brief A DownLink Scheduler for rtPS Flows
+ *
+ * The DL Scheduler assigns the available bandwidth in the following order:
+ * - IR Connections
+ * - Broadcast Connections
+ * - Basic and Primary Connections
+ * - UGS Connections
+ * - rtPS Connections
+ * - nrtPS Connections
+ * - BE Connections
+ * All rtPS flows that have packets in the queue can transmit at least one
+ * packet, according to the available bandwidth.
+ */
 void
 BSSchedulerRtps::Schedule (void)
 {
-  /**
-   * \brief  A DownLink Scheduler for rtPS Flows
-   *
-   * The DL Scheduler assigns the available bandwidth in the following order:
-   *         - IR Connections
-   *         - Broadcast Connections
-   *         - Basic and Primary Connections
-   *         - UGS Connections
-   * - rtPS Connections
-   *         - nrtPS Connections
-   *         - BE Connections
-   * All rtPS flows that have packets in the queue can transmit at least one
-   * packet, according to the available bandwidth.
-   */
 
   uint32_t availableSymbols = GetBs ()->GetNrDlSymbols ();
 
--- a/wscript	Fri Dec 16 18:50:05 2011 +0100
+++ b/wscript	Fri Dec 16 18:51:18 2011 +0100
@@ -361,6 +361,10 @@
                 conf.report_optional_feature("static", "Static build", False,
                                              "Link flag -Wl,--whole-archive,-Bstatic does not work")
 
+    # Set this so that the lists won't be printed at the end of this
+    # configure command.
+    conf.env['PRINT_BUILT_MODULES_AT_END'] = False
+
     conf.env['MODULES_NOT_BUILT'] = []
 
     conf.sub_config('src')
@@ -782,6 +786,10 @@
     # and module test libraries have been set.
     bld.add_subdirs('utils')
 
+    # Set this so that the lists will be printed at the end of this
+    # build command.
+    bld.env['PRINT_BUILT_MODULES_AT_END'] = True
+
     if Options.options.run:
         # Check that the requested program name is valid
         program_name, dummy_program_argv = wutils.get_run_program(Options.options.run, wutils.get_command_template(env))
@@ -806,14 +814,8 @@
         return
     env = bld.env
 
-    # Don't print the lists if a program is being run, a Python
-    # program is being run, this a clean, or this is a distribution
-    # clean.
-    if ((not Options.options.run)
-        and (not Options.options.pyrun) 
-        and ('clean' not in Options.commands)
-        and ('distclean' not in Options.commands)
-        and ('shell' not in Options.commands)):
+    # Only print the lists if a build was done.
+    if (env['PRINT_BUILT_MODULES_AT_END']):
 
         # Print the list of built modules.
         print
@@ -828,6 +830,10 @@
             print_module_names(env['MODULES_NOT_BUILT'])
             print
 
+        # Set this so that the lists won't be printed until the next
+        # build is done.
+        bld.env['PRINT_BUILT_MODULES_AT_END'] = False
+
     # Write the build status file.
     build_status_file = os.path.join(bld.out_dir, 'build-status.py')
     out = open(build_status_file, 'w')
@@ -973,6 +979,10 @@
 	bld.cmd = "build"
 	bld.execute()
 
+        # Set this so that the lists won't be printed when the user
+        # exits the shell.
+        bld.env['PRINT_BUILT_MODULES_AT_END'] = False
+
         if sys.platform == 'win32':
             shell = os.environ.get("COMSPEC", "cmd.exe")
         else: