merge
authorGustavo J. A. M. Carneiro <gjc@inescporto.pt>
Sat, 27 Sep 2008 15:17:37 +0100
changeset 3720 e09a1bd54909
parent 3719 3307abd75322 (current diff)
parent 3718 f22f8ab3f6f5 (diff)
child 3721 3748390f3608
merge
--- a/.hgtags	Sat Sep 27 15:06:38 2008 +0100
+++ b/.hgtags	Sat Sep 27 15:17:37 2008 +0100
@@ -20,3 +20,5 @@
 319eb29611b18998abbad01548825643a8017bcb ns-3.2-RC2
 d783a951f8f5e64b33bc518f0415f76cae1ca6f3 ns-3.2-RC2-bis
 fa1c7b813873cfa251be7d1b7cea38373fe82fa1 ns-3.2-RC3
+68218c266a844f9fbda34a0ffddb1ae2adebd4b0 ns-3.2-RC4
+2ecac911b3ec40d73ab8301471bea6d9ba5b9885 ns-3.2
--- a/RELEASE_NOTES	Sat Sep 27 15:06:38 2008 +0100
+++ b/RELEASE_NOTES	Sat Sep 27 15:17:37 2008 +0100
@@ -43,8 +43,8 @@
     It is now possible to run simulations synchronized on the real-world
     wall-clock time (contributed by Craig Dowell).
 
-  d) Network Simulation Craddle
-    It is now possible to use the Network Simulation Craddle 
+  d) Network Simulation Cradle
+    It is now possible to use the Network Simulation Cradle 
     (http://www.wand.net.nz/~stj2/nsc/) in ns-3 and run simulations 
     using various versions of kernel TCP network stacks. (contributed
     by Florian Westphal as part of his Google Summer of Code work)
--- a/bindings/python/ns3module_helpers.cc	Sat Sep 27 15:06:38 2008 +0100
+++ b/bindings/python/ns3module_helpers.cc	Sat Sep 27 15:17:37 2008 +0100
@@ -33,6 +33,9 @@
     }
     virtual void Notify ()
     {
+        PyGILState_STATE __py_gil_state;
+        __py_gil_state = (PyEval_ThreadsInitialized() ? PyGILState_Ensure() : (PyGILState_STATE) 0);
+        
         PyObject *retval = PyObject_CallObject(m_callback, m_args);
         if (retval) {
             if (retval != Py_None) {
@@ -43,6 +46,9 @@
         } else {
              PyErr_Print();
         }
+
+        if (PyEval_ThreadsInitialized())
+            PyGILState_Release(__py_gil_state);
     }
 };
 
--- a/doc/manual/attributes.texi	Sat Sep 27 15:06:38 2008 +0100
+++ b/doc/manual/attributes.texi	Sat Sep 27 15:17:37 2008 +0100
@@ -2,6 +2,15 @@
 @chapter Attributes 
 @anchor{chap:Attributes}
 
+@menu
+* Object Overview::
+* Attribute Overview::
+* Extending attributes::
+* Adding new class type::
+* ConfigStore::
+@end menu
+
+
 In ns-3 simulations, there are two main aspects to configuration:
 @itemize @bullet
 @item the simulation topology and how objects are connected 
@@ -48,8 +57,7 @@
 @node Smart pointers
 @subsection Smart pointers
 
-As introduced above in @ref{Smart Pointers 101}, ns-3 objects 
-are memory managed by a 
+As introduced in the ns-3 tutorial, ns-3 objects are memory managed by a 
 @uref{http://en.wikipedia.org/wiki/Smart_pointer,,reference counting smart pointer implementation}, @code{class ns3::Ptr}. 
 
 Smart pointers are used extensively in the ns-3 APIs, to avoid passing
@@ -496,6 +504,7 @@
 are advised to check carefully multiple times that they got these right.
 
 
+@node Adding new class type
 @section Adding new class type to the attribute system
 
 From the perspective of the user who writes a new class in the system and
@@ -557,3 +566,158 @@
 modeler must specify these operators and the string syntactical representation 
 of an instance of the new class.
 
+@node ConfigStore
+@section ConfigStore
+
+@strong{Feedback requested:}  This is an experimental feature of ns-3.
+It is not in the main tree.  If you like this feature and would like
+to provide feedback on it, please email us.
+
+Values for ns-3 attributes can be stored in an ascii text file and
+loaded into a future simulation.  This feature is known as the
+ns-3 ConfigStore.  
+The ConfigStore code is in @code{src/contrib/}.  It is not yet main-tree
+code, because we are seeking some user feedback. 
+
+We can explore this system by using an example.  Copy the @code{csma-bridge.cc}
+file to the scratch directory:
+@verbatim
+  cp examples/csma-bridge.cc scratch/
+  ./waf
+@end verbatim
+
+Let's edit it to add the ConfigStore feature.  First, add an include statement,
+and then add these lines:
+
+@verbatim
+#include "contrib-module.h"
+...
+int main (...)
+{
+  // setup topology
+
+  // Invoke just before entering Simulator::Run ()
+  ConfigStore config;
+  config.Configure ();
+
+  Simulator::Run ();
+}
+@end verbatim
+
+There is an attribute that governs whether the Configure() call either
+stores a simulation configuration in a file and exits, or whether
+it loads a simulation configuration file annd proceeds.  First,
+the @code{LoadFilename} attribute is checked, and if non-empty,
+the program loads the configuration from the filename provided.
+If LoadFilename is empty, and if the @code{StoreFilename} attribute is 
+populated, the configuration will be written to the output filename
+specified.
+
+While it is possible to generate a sample config file and lightly
+edit it to change a couple of values, there are cases where this
+process will not work because the same value on the same object
+can appear multiple times in the same automatically-generated 
+configuration file under different configuration paths.
+
+As such, the best way to use this class is to use it to generate
+an initial configuration file, extract from that configuration
+file only the strictly necessary elements, and move these minimal
+elements to a new configuration file which can then safely
+be edited and loaded in a subsequent simulation run. 
+
+So, let's do that as an example.  We'lll run the program once
+to create a configure file, and look at it. 
+If you are running bash shell, the below command should work (which illustrates
+how to set an attribute from the command line):
+@verbatim
+./build/debug/scratch/csma-bridge --ns3::ConfigStore::StoreFilename=test.config
+@end verbatim
+or, if the above does not work (the above requires rpath support), try this:
+@verbatim
+./waf --command-template="%s --ns3::ConfigStore::StoreFilename=test.config" --run scratch/csma-bridge
+@end verbatim
+
+Running the program should yield a "test.config" output configuration file 
+that looks like this:
+@verbatim
+/$ns3::NodeListPriv/NodeList/0/$ns3::Node/DeviceList/0/$ns3::CsmaNetDevice/Addre
+ss 00:00:00:00:00:01
+/$ns3::NodeListPriv/NodeList/0/$ns3::Node/DeviceList/0/$ns3::CsmaNetDevice/Frame
+Size 1518
+/$ns3::NodeListPriv/NodeList/0/$ns3::Node/DeviceList/0/$ns3::CsmaNetDevice/SendE
+nable true
+/$ns3::NodeListPriv/NodeList/0/$ns3::Node/DeviceList/0/$ns3::CsmaNetDevice/Recei
+veEnable true
+/$ns3::NodeListPriv/NodeList/0/$ns3::Node/DeviceList/0/$ns3::CsmaNetDevice/TxQue
+ue/$ns3::DropTailQueue/MaxPackets 100
+/$ns3::NodeListPriv/NodeList/0/$ns3::Node/DeviceList/0/$ns3::CsmaNetDevice/Mtu 1
+500
+...
+@end verbatim
+
+The above lists, for each object in the script topology, the value of each 
+registered attribute.  The syntax of this file is that the unique name
+of the attribute (in the attribute namespace) is specified on each line,
+followed by a value.  
+
+This file is intended to be a convenient record of the parameters that were 
+used in a given simulation run, and can be stored with simulation
+output files.  Additionally, 
+this file can also be used to parameterize a simulation, instead of
+editing the script or passing in command line arguments.   For instance,
+a person wanting to run the simulation can examine and tweak the values
+in a pre-existing configuration file, and pass the file to the
+program.   In this case, the relevant commands are:
+@verbatim
+./build/debug/scratch/csma-bridge --ns3::ConfigStore::LoadFilename=test.config
+@end verbatim
+or, if the above does not work (the above requires rpath support), try this:
+@verbatim
+./waf --command-template="%s --ns3::ConfigStore::LoadFilename=test.config" --run scratch/csma-bridge
+@end verbatim
+
+@subsection GTK-based ConfigStore
+
+There is a GTK-based front end for the ConfigStore.  This allows users
+to use a GUI to access and change variables.  Screenshots of this
+feature are available in the 
+@uref{http://www.nsnam.org/docs/ns-3-overview.pdf,,ns-3 Overview} presentation.
+
+To use this feature, one must install libgtk and libgtk-dev; an example
+Ubuntu installation command is:
+@verbatim
+sudo apt-get install libgtk2.0-0 libgtk2.0-dev
+@end verbatim
+To check whether it is configured or not, check the output of the
+./waf configure step:
+@verbatim
+---- Summary of optional NS-3 features:
+Threading Primitives          : enabled
+Real Time Simulator           : enabled
+GtkConfigStore                : not enabled (library 'gtk+-2.0 >= 2.12' not found)
+@end verbatim
+
+In the above example, it was not enabled, so it cannot be used until a
+suitable version is installed and ./waf configure; ./waf is rerun.
+
+Usage is almost the same as the non-GTK-based version:
+@verbatim
+  // Invoke just before entering Simulator::Run ()
+  GtkConfigStore config;
+  config.Configure ();
+@end verbatim
+
+Now, when you run the script, a GUI should pop up, allowing you to open
+menus of attributes on different nodes/objects, and then launch the
+simulation execution when you are done.  
+
+@subsection Future work
+There are a couple of possible improvements:
+@itemize bullet
+@item save a unique version number with date and time at start of file
+@item save rng initial seed somewhere.
+@item make each RandomVariable serialize its own initial seed and re-read
+it later
+@item add the default values
+@end itemize
+
--- a/doc/manual/manual.texi	Sat Sep 27 15:06:38 2008 +0100
+++ b/doc/manual/manual.texi	Sat Sep 27 15:17:37 2008 +0100
@@ -81,9 +81,11 @@
 * Random variables::
 * Callbacks::
 * Attributes::
+* RealTime::
 * Packets::
 * Sockets APIs::
 * Node and Internet Stack::
+* TCP::
 * Routing overview::
 * Troubleshooting
 @end menu
@@ -91,10 +93,12 @@
 @include random.texi
 @include callbacks.texi
 @include attributes.texi
+@include realtime.texi
 @include packets.texi
 @include sockets.texi
 @include node.texi
 @c @include output.texi
+@include tcp.texi
 @include routing.texi
 @c @include other.texi
 @include troubleshoot.texi
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/manual/realtime.texi	Sat Sep 27 15:17:37 2008 +0100
@@ -0,0 +1,100 @@
+@node RealTime
+@chapter Real-Time Scheduler
+@anchor{chap:RealTime}
+
+ns-3 has been designed for integration into testbed and virtual machine
+environments.  To integrate with real network stacks and emit/consume
+packets, a real-time scheduler is needed to try to lock the simulation
+clock with the hardware clock.  We describe here a component of this:
+the RealTime scheduler. 
+
+The purpose of the realtime scheduler is to cause the progression of 
+the simulation clock to occur synchronously with respect to some 
+external time base. Without the presence of an external time base 
+(wall clock), simulation time jumps instantly from one simulated time to 
+the next.
+
+@section Behavior
+
+When using a non-realtime scheduler (the default in ns-3), the simulator
+advances the simulation time to the next scheduled event.  During event
+execution, simulation time is frozen.  With the realtime scheduler, the 
+behavior is similar from the perspective of simulation models (i.e.,
+simulation time is frozen during event execution), but between events,
+the simulator will attempt to keep the simulation clock aligned with
+the machine clock.
+
+When an event is finished executing, and the scheduler moves to the next
+event, the scheduler compares the next event execution time with the
+machine clock.  If the next event is scheduled for a future time,
+the simulator sleeps until that realtime is reached and then executes
+the next event.
+
+It may happen that, due to the processing inherent in the execution
+of simulation events, that the simulator cannot keep up with realtime.
+In such a case, it is up to the user configuration what to do.  There
+are two ns-3 attributes that govern the behavior.  The first is
+@code{ns3::RealTimeSimulatorImpl::SynchronizationMode}.  The two
+entries possible for this attribute are @code{BestEffort} (the default)
+or @code{HardLimit}.  In "BestEffort" mode, the simulator will just
+try to catch up to realtime by executing events until it reaches
+a point where the next event is in the (realtime) future, or else
+the simulation ends.  In BestEffort mode, then, it is possible for
+the simulation to consume more time than the wall clock time.  The
+other option "HardLimit" will cause the simulation to abort if the tolerance
+threshold is exceeded.  This attribute is
+@code{ns3::RealTimeSimulatorImpl::HardLimit} and the default is 0.1 seconds.   
+
+A different mode of operation is one in which simulated time is @strong{not}
+frozen during an event execution.  This mode of realtime simulation was
+implemented but removed from the ns-3 tree because of questions of whether
+it would be useful.  If users are interested in a realtime simulator
+for which simulation time does not freeze during event execution (i.e.,
+every call to @code{Simulator::Now()} returns the current wall clock time,
+not the time at which the event started executing), please contact the
+ns-developers mailing list.
+
+@section Usage
+
+The usage of the realtime simulator is straightforward, from a scripting
+perspective.  Users just need to set the attribute 
+@code{SimulatorImplementationType} to the Realtime simulator, such as follows:
+@verbatim
+  GlobalValue::Bind ("SimulatorImplementationType",
+    StringValue ("ns3::RealtimeSimulatorImpl"));
+@end verbatim
+
+There is a script in @code{examples/realtime-udp-echo.cc} that has an
+example of how to configure the realtime behavior.  Try:
+@verbatim
+./waf --run realtime-udp-echo
+@end verbatim
+
+Whether the simulator will work in a best effort or hard limit policy
+fashion is governed by the attributes explained in the previous section.
+
+@section Implementation
+
+The implementation is contained in the following files:
+@itemize @bullet
+@item @code{src/simulator/realtime-simulator-impl.{cc,h}}
+@item @code{src/simulator/wall-clock-synchronizer.{cc,h}}
+@end itemize
+
+In order to create a realtime scheduler, to a first approximation you 
+just want to cause simulation time jumps to consume real time. We propose 
+doing this using a combination of sleep- and busy- waits. Sleep-waits cause 
+the calling process (thread) to yield the processor for some amount of time. 
+Even though this specified amount of time can be passed to nanosecond 
+resolution, it is actually converted to an OS-specific granularity. 
+In Linux, the granularity is called a Jiffy. Typically this resolution is 
+insufficient for our needs (on the order of a ten milliseconds), so we 
+round down and sleep for some smaller number of Jiffies. The process is 
+then awakened after the specified number of Jiffies has passed. At this 
+time, we have some residual time to wait. This time is generally smaller 
+than the minimum sleep time, so we busy-wait for the remainder of the time. 
+This means that the thread just sits in a for loop consuming cycles until 
+the desired time arrives. After the combination of sleep- and busy-waits, 
+the elapsed realtime (wall) clock should agree with the simulation time 
+of the next event and the simulation proceeds. 
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/manual/tcp.texi	Sat Sep 27 15:17:37 2008 +0100
@@ -0,0 +1,342 @@
+@node TCP
+@chapter TCP models in ns-3
+@anchor{chap:TCP}
+
+This chapter describes the TCP models available in ns-3.
+
+@section Generic support for TCP
+
+ns-3 was written to support multiple TCP implementations.  The 
+implementations inherit from a few common header classes in the
+@code{src/node} directory, so that user code can swap out implementations
+with minimal changes to the scripts.
+
+There are two important abstract base classes:
+@itemize @bullet
+@item @code{class TcpSocket}:  This is defined in @code{src/node/tcp-socket.{cc,h}}.  This class exists for hosting TcpSocket attributes that can be
+reused across different implementations.  For instance, 
+@code{TcpSocket::SetInitialCwnd()} can be used for any of the implementations
+that derive from @code{class TcpSocket}.
+@item @code{class TcpSocketFactory}:  This is used by applications to
+create TCP sockets.  A typical usage can be seen in this snippet:
+@verbatim
+  // Create the socket if not already created
+  if (!m_socket)
+    {
+      m_socket = Socket::CreateSocket (GetNode(), m_tid);
+      m_socket->Bind (m_local);
+      ...
+    }
+@end verbatim
+The parameter @code{m_tid} controls the TypeId of the actual Tcp Socket
+implementation that is instantiated.  This way, the application can be
+written generically and different socket implementations can be swapped out
+by specifying the TypeId.
+@end itemize  
+
+@section ns-3 TCP
+
+ns-3 contains a port of the TCP model from 
+@uref{http://www.ece.gatech.edu/research/labs/MANIACS/GTNetS/index.html,,GTNetS}.  This model is a full TCP, in that it is 
+bidirectional and attempts to model the connection setup and
+close logic.  In fact, it is a more complete implementation of the TCP
+state machine than ns-2's "FullTcp" model.  This TCP model was originally 
+written by George Riley
+as part of GTNetS and ported to ns-3 by Raj Bhattacharjea.
+
+The implementation of TCP is contained in the following files:
+@verbatim
+src/internet-stack/tcp-header.{cc,h}
+src/internet-stack/tcp-l4-protocol.{cc,h}
+src/internet-stack/tcp-socket-factory-impl.{cc,h}
+src/internet-stack/tcp-socket-impl.{cc,h}
+src/internet-stack/tcp-typedefs.h
+src/internet-stack/rtt-estimator.{cc,h}
+src/internet-stack/sequence-number.{cc,h}
+@end verbatim
+
+@subsection Usage
+
+The file @code{examples/tcp-star-server.cc} contains an example that
+makes use of @code{ns3::OnOffApplication} and @code{ns3::PacketSink} 
+applications.
+
+Using the helper functions defined in @code{src/helper}, here is how
+one would create a TCP receiver:
+@verbatim
+  // Create a packet sink on the star "hub" to receive these packets
+  uint16_t port = 50000;
+  Address sinkLocalAddress(InetSocketAddress (Ipv4Address::GetAny (), port));
+  PacketSinkHelper sinkHelper ("ns3::TcpSocketFactory", sinkLocalAddress);
+  ApplicationContainer sinkApp = sinkHelper.Install (serverNode);
+  sinkApp.Start (Seconds (1.0));
+  sinkApp.Stop (Seconds (10.0));
+@end verbatim
+
+Similarly, the below snippet configures OnOffApplication traffic
+source to use
+TCP:
+@verbatim
+  // Create the OnOff applications to send TCP to the server
+  OnOffHelper clientHelper ("ns3::TcpSocketFactory", Address ());
+@end verbatim
+
+The careful reader will note above that we have specified the TypeId
+of an abstract base class @code{TcpSocketFactory}.  How does the
+script tell ns-3 that it wants the native ns-3 TCP vs. some other one?
+Well, when internet stacks are added to the node, the default
+TCP implementation that is aggregated to the node is the ns-3 TCP.
+This can be overridden as we show below when using Network
+Simulation Cradle.  So, by default, when using the ns-3 helper API,
+the TCP that is aggregated to nodes with an Internet stack is the
+native ns-3 TCP.
+
+Once a TCP socket is created, you will want to follow conventional
+socket logic and either connect() and send() (for a TCP client)
+or bind(), listen(), and accept() (for a TCP server).  
+@xref{Sockets APIs,,Sockets API} for a review of how sockets are used
+in ns-3.
+
+To configure behavior of TCP, a number of parameters are exported through
+the @ref{Attributes,,ns-3 attribute system}.  These are documented in the
+@uref{http://www.nsnam.org/doxygen/classns3_1_1_tcp_socket.html,,Doxygen} 
+for @code{class TcpSocket}.
+
+@subsection Current limitations
+@itemize @bullet
+@item Only Tahoe congestion control is presently supported.
+@item Only IPv4 is supported (IPv6 support will start to be added in ns-3.3).
+@item @uref{http://www.nsnam.org/bugzilla/show_bug.cgi?id=198,,Bug 198}:  TcpSocketImpl doesn't send acks with data packets in two-way transfers
+@item @uref{http://www.nsnam.org/bugzilla/show_bug.cgi?id=250,,Bug 250}:  Tcp breaks if you set the DelAckCount parameter to be greater than 2
+@item @uref{http://www.nsnam.org/bugzilla/show_bug.cgi?id=311,,Bug 311}:  Tcp socket close returns -1 but does not set errno.
+@end itemize
+
+@section Network Simulation Cradle
+
+The @uref{http://www.wand.net.nz/~stj2/nsc/,,Network Simulation Cradle (NSC)} 
+is a framework for wrapping real-world network
+code into simulators, allowing simulation of real-world behavior at little 
+extra cost.  This work has been validated by comparing situations using 
+a test network with the same situations in the simulator. To date, it has 
+been shown that the NSC is able to produce extremely accurate results.
+NSC supports four real world stacks: FreeBSD, OpenBSD, lwIP and Linux.
+Emphasis has been placed on not changing any of the network stacks by hand. 
+Not a single line of code has been changed in the network protocol 
+implementations of any of the above four stacks. However, a custom C 
+parser was built to programmatically change source code.
+
+NSC has previously been ported to ns-2 and OMNeT++, and recently 
+was added to ns-3.  This section describes the ns-3 port of NSC and
+how to use it.
+
+@subsection Prerequisites
+
+Presently, NSC has been tested and shown to work on these platforms:
+Linux i386 and Linux x86-64.  NSC does not support powerpc at the moment.
+
+NSC requires the packages mercurial, flex, and bison.  
+
+@subsection Configuring and Downloading
+
+NSC is disbled by default and must be explicitly configured in.  To try
+this, type
+@verbatim
+./waf configure --enable-nsc
+@end verbatim
+the output of the configuration will show something like:
+@verbatim
+Checking for NSC supported architecture x86_64                           : ok  
+Pulling nsc updates from https://secure.wand.net.nz/mercurial/nsc
+pulling from https://secure.wand.net.nz/mercurial/nsc
+searching for changes
+no changes found
+---- Summary of optional NS-3 features:
+...
+Network Simulation Cradle     : enabled
+...
+@end verbatim 
+if successful.  Note that the configure script pulls a recent copy of
+NSC from a mercurial repository.  This download will not work if you are not
+online.
+
+If everything went OK, you will see a directory called "nsc" in the top-level
+directory, with contents like this:
+@verbatim
+audit.sh            linux-2.6/          openbsd3/           scons-time.py*
+ChangeLog           linux-2.6.18/       README              SConstruct 
+config.log          linux-2.6.26/       sconsign.py*        sim/
+freebsd5/           lwip-1.3.0/         scons-LICENSE       test/
+globaliser/         lwip-HEAD/          scons-local-1.0.1/  
+INSTALL             ns/                 scons.py*           
+LICENSE             omnetpp/            scons-README        
+@end verbatim
+
+@subsection Building and validating
+
+Building ns-3 with nsc support is the same as building it without; no
+additional arguments are needed for waf.  Building nsc may take some time
+compared to ns-3; it is interleaved in the ns-3 building process.
+
+Try running the regression tests: @code{./waf --regression}.  If NSC has
+been successfully built, the following test should show up in the results:
+@verbatim
+PASS test-tcp-nsc-lfn
+@end verbatim
+
+This confirms that NSC is ready to use.
+
+@subsection Usage
+There are a few example files.  Try
+@verbatim
+./waf --run tcp-nsc-zoo
+./waf --run tcp-nsc-lfn
+@end verbatim
+These examples will deposit some @code{.pcap} files in your directory,
+which can be examined by tcpdump or wireshark.
+
+Let's look at the @code{examples/tcp-nsc-zoo.cc} file for some typical
+usage.  How does it differ from using native ns-3 TCP?  There is one
+main configuration line, when using NSC and the ns-3 helper API, that needs
+to be set:
+@verbatim
+  InternetStackHelper internetStack;
+
+  internetStack.SetNscStack ("liblinux2.6.26.so");
+  // this switches nodes 0 and 1 to NSCs Linux 2.6.26 stack.
+  internetStack.Install (n.Get(0));
+  internetStack.Install (n.Get(1));
+@end verbatim
+
+The key line is the @code{SetNscStack}.  This tells the InternetStack
+helper to aggregate instances of NSC TCP instead of native ns-3 TCP
+to the remaining nodes.  It is important that this function be called
+@strong{before} callling the @code{Install()} function, as shown above.
+
+Which stacks are available to use?  Presently, the focus has been on
+Linux 2.6.18 and Linux 2.6.26 stacks for ns-3.  To see which stacks
+were built, one can execute the following find command at the ns-3 top level
+directory:
+@verbatim
+~/ns-3.2> find nsc -name "*.so" -type f 
+nsc/linux-2.6.18/liblinux2.6.18.so
+nsc/linux-2.6.26/liblinux2.6.26.so
+@end verbatim
+This tells us that we may either pass the library name liblinux2.6.18.so or 
+liblinux2.6.26.so to the above configuration step.
+
+@subsection Stack configuration
+NSC TCP shares the same configuration attributes that are common
+across TCP sockets, as described above and documented in 
+@uref{http://www.nsnam.org/doxygen/classns3_1_1_tcp_socket.html,,Doxygen} 
+
+Additionally, NSC TCP exports a lot of configuration variables into the 
+ns-3 @ref{Attributes} system, via a @uref{http://en.wikipedia.org/wiki/Sysctl,,
+sysctl}-like interface.  In the @code{examples/tcp-nsc-zoo} example, you
+can see the following configuration:
+@verbatim
+  // this disables TCP SACK, wscale and timestamps on node 1 (the attributes represent sysctl-values).
+  Config::Set ("/NodeList/1/$ns3::Ns3NscStack<linux2.6.26>/net.ipv4.tcp_sack", StringValue ("0"));
+  Config::Set ("/NodeList/1/$ns3::Ns3NscStack<linux2.6.26>/net.ipv4.tcp_timestamps", StringValue ("0"));
+  Config::Set ("/NodeList/1/$ns3::Ns3NscStack<linux2.6.26>/net.ipv4.tcp_window_scaling", StringValue ("0"));
+@end verbatim
+These additional configuration variables are not available to native ns-3
+TCP.
+
+@subsection NSC API
+
+This subsection describes the API that NSC presents to ns-3 or any other
+simulator.  NSC provides its API in the form of a number of classes that
+are defined in @code{sim/sim_interface.h} in the nsc directory.
+
+@itemize @bullet
+@item @strong{INetStack}
+INetStack contains the 'low level' operations for the operating system 
+network stack, e.g. in and output functions from and to the network stack 
+(think of this as the 'network driver interface'. There are also functions 
+to create new TCP or UDP sockets.
+@item @strong{ISendCallback}
+This is called by NSC when a packet should be sent out to the network. 
+This simulator should use this callback to re-inject the packet into the 
+simulator so the actual data can be delivered/routed to its destination, 
+where it will eventually be handed into Receive() (and eventually back to the 
+receivers NSC instance via INetStack->if_receive() ).
+@item @strong{INetStreamSocket}
+This is the structure defining a particular connection endpoint (file 
+descriptor). It contains methods to operate on this endpoint, e.g. connect, 
+disconnect, accept, listen, send_data/read_data, ...
+@item @strong{IInterruptCallback}
+This contains the wakeup callback, which is called by NSC whenever 
+something of interest happens. Think of wakeup() as a replacement of the 
+operating systems wakeup function: Whenever the operating system would 
+wake up a process that has been waiting for an operation to complete (for 
+example the TCP handshake during connect()), NSC invokes the wakeup() callback 
+to allow the simulator to check for state changes in its connection endpoints. 
+@end itemize
+
+@subsection ns-3 implementation
+
+The ns-3 implementation makes use of the above NSC API, and is implemented
+as follows.
+
+The three main parts are:
+@itemize @bullet
+@item @code{ns3::NscTcpL4Protocol}:  a subclass of Ipv4L4Protocol (and two nsc classes: ISendCallback and IInterruptCallback)
+@item @code{ns3::NscTcpSocketImpl}: a subclass of TcpSocket 
+@item @code{ns3::NscTcpSocketFactoryImpl}:  a factory to create new NSC
+sockets
+@end itemize
+
+@code{src/internet-stack/nsc-tcp-l4-protocol} is the main class. Upon 
+Initialization, it loads an nsc network stack to use (via dlopen()). Each 
+instance of this class may use a different stack. The stack 
+(=shared library) to use is set using the SetNscLibrary() method (at 
+this time its called indirectly via the internet stack helper). The nsc 
+stack is then set up accordingly (timers etc). The 
+NscTcpL4Protocol::Receive() function hands the packet it receives (must be 
+a complete tcp/ip packet) to the nsc stack for further processing. 
+To be able to send packets, this class implements the nsc send_callback 
+method. This method is called by nsc whenever the nsc stack wishes to 
+send a packet out to the network. Its arguments are a raw buffer, 
+containing a complete TCP/IP packet, and a length value. This method 
+therefore has to convert the raw data to a Ptr<Packet> usable by ns-3. 
+In order to avoid various ipv4 header issues, the nsc ip header is not 
+included. Instead, the tcp header and the actual payload are put into the 
+Ptr<Packet>, after this the Packet is passed down to layer 3 for sending 
+the packet out (no further special treatment is needed in the send code 
+path).
+
+This class calls @code{ns3::NscTcpSocketImpl} both from the nsc wakeup() 
+callback and from the Receive path (to ensure that possibly queued data 
+is scheduled for sending).
+
+
+@code{src/internet-stack/nsc-tcp-socket-impl} implements the nsc socket 
+interface. Each instance has its own nscTcpSocket. Data that is Send() 
+will be handed to the nsc stack via m_nscTcpSocket->send_data(). (and not 
+to nsc-tcp-l4, this is the major difference compared to ns-3 TCP). The 
+class also queues up data that is Send() before the underlying 
+descriptor has entered an ESTABLISHED state. This class is called from 
+the nsc-tcp-l4 class, when the nsc-tcp-l4 wakeup() callback is invoked by 
+nsc. nsc-tcp-socket-impl then checks the current connection state 
+(SYN_SENT, ESTABLISHED, LISTEN...) and schedules appropriate callbacks as 
+needed, e.g. a LISTEN socket will schedule Accept to see if a new 
+connection must be accepted, an ESTABLISHED socket schedules any pending 
+data for writing, schedule a read callback, etc.
+
+Note that @code{ns3::NscTcpSocketImpl} does not interact with nsc-tcp 
+directly: instead, data is redirected to nsc. nsc-tcp calls the 
+nsc-tcp-sockets of a node when its wakeup callback is invoked by nsc. 
+
+@subsection Limitations
+@itemize @bullet
+@item NSC only works on single-interface nodes; attempting to run it on
+a multi-interface node will cause a program error.  This limitation should
+be fixed by ns-3.3.
+@item Cygwin and OS X PPC are not presently supported
+@item The non-Linux stacks of NSC are not supported
+@item NSC's integration into the build system presently requires on-line
+access and mercurial, and is a slow download.
+@end itemize
+
+For more information, see
+@uref{http://www.nsnam.org/wiki/index.php/Network_Simulation_Cradle_Integration,, this wiki page}.
--- a/doc/tutorial/introduction.texi	Sat Sep 27 15:06:38 2008 +0100
+++ b/doc/tutorial/introduction.texi	Sat Sep 27 15:17:37 2008 +0100
@@ -213,7 +213,7 @@
 Once you have source code downloaded to your local system, you will need 
 to compile that source to produce usable programs.  Just as in the case of
 source code management, there are many tools available to perform this 
-function.  Probably the most will known of these tools is @code{make}.  Along
+function.  Probably the most well known of these tools is @code{make}.  Along
 with being the most well known, @code{make} is probably the most difficult to
 use in a very large and highly configurable system.  Because of this, many
 alternatives have been developed.  Recently these systems have been developed
--- a/examples/csma-bridge.cc	Sat Sep 27 15:06:38 2008 +0100
+++ b/examples/csma-bridge.cc	Sat Sep 27 15:17:37 2008 +0100
@@ -127,19 +127,21 @@
   // Create an optional packet sink to receive these packets
   PacketSinkHelper sink ("ns3::UdpSocketFactory",
                          Address (InetSocketAddress (Ipv4Address::GetAny (), port)));
-  sink.Install (terminals.Get (1));
+  app = sink.Install (terminals.Get (1));
+  app.Start (Seconds (0.0));
 
   // 
   // Create a similar flow from n3 to n0, starting at time 1.1 seconds
   //
   onoff.SetAttribute ("Remote", 
                       AddressValue (InetSocketAddress (Ipv4Address ("10.1.1.1"), port)));
-  ApplicationContainer app2 = onoff.Install (terminals.Get (3));
+  app = onoff.Install (terminals.Get (3));
+  app.Start (Seconds (1.1));
+  app.Stop (Seconds (10.0));
 
-  sink.Install (terminals.Get (0));
+  app = sink.Install (terminals.Get (0));
+  app.Start (Seconds (0.0));
 
-  app2.Start (Seconds (1.1));
-  app2.Stop (Seconds (10.0));
 
   //
   // Configure tracing of all enqueue, dequeue, and NetDevice receive events.
--- a/examples/csma-bridge.py	Sat Sep 27 15:06:38 2008 +0100
+++ b/examples/csma-bridge.py	Sat Sep 27 15:17:37 2008 +0100
@@ -107,19 +107,20 @@
     # Create an optional packet sink to receive these packets
     sink = ns3.PacketSinkHelper("ns3::UdpSocketFactory",
                                 ns3.Address(ns3.InetSocketAddress(ns3.Ipv4Address.GetAny(), port)))
-    sink.Install(ns3.NodeContainer(terminals.Get(1)))
+    app = sink.Install(ns3.NodeContainer(terminals.Get(1)))
+    app.Start (ns3.Seconds (0.0))
 
     # 
     # Create a similar flow from n3 to n0, starting at time 1.1 seconds
     #
     onoff.SetAttribute("Remote", 
                        ns3.AddressValue(ns3.InetSocketAddress(ns3.Ipv4Address("10.1.1.1"), port)))
-    app2 = onoff.Install(ns3.NodeContainer(terminals.Get(3)))
+    app = onoff.Install(ns3.NodeContainer(terminals.Get(3)))
+    app.Start(ns3.Seconds(1.1))
+    app.Stop(ns3.Seconds(10.0))
 
-    sink.Install(ns3.NodeContainer(terminals.Get(0)))
-
-    app2.Start(ns3.Seconds(1.1))
-    app2.Stop(ns3.Seconds(10.0))
+    app = sink.Install(ns3.NodeContainer(terminals.Get(0)))
+    app.Start (ns3.Seconds (0.0))
 
     #
     # Configure tracing of all enqueue, dequeue, and NetDevice receive events.
--- a/examples/csma-one-subnet.cc	Sat Sep 27 15:06:38 2008 +0100
+++ b/examples/csma-one-subnet.cc	Sat Sep 27 15:17:37 2008 +0100
@@ -61,8 +61,8 @@
 // Explicitly create the nodes required by the topology (shown above).
 //
   NS_LOG_INFO ("Create nodes.");
-  NodeContainer c;
-  c.Create (4);
+  NodeContainer nodes;
+  nodes.Create (4);
 
   NS_LOG_INFO ("Build Topology");
   CsmaHelper csma;
@@ -70,24 +70,19 @@
   csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
 //
 // Now fill out the topology by creating the net devices required to connect
-// the nodes to the channels and hooking them up.  AddIpv4CsmaNetDevice will
-// create a net device, add a MAC address (in memory of the pink flamingo) and
-// connect the net device to a nodes and also to a channel. the 
-// AddIpv4CsmaNetDevice method returns a net device index for the net device
-// created on the node.  Interpret nd0 as the net device we created for node
-// zero.
+// the nodes to the channels and hooking them up.
 //
-  NetDeviceContainer nd0 = csma.Install (c);
+  NetDeviceContainer devices = csma.Install (nodes);
 
   InternetStackHelper internet;
-  internet.Install (c);
+  internet.Install (nodes);
 
 // We've got the "hardware" in place.  Now we need to add IP addresses.
 //
   NS_LOG_INFO ("Assign IP Addresses.");
   Ipv4AddressHelper ipv4;
   ipv4.SetBase ("10.1.1.0", "255.255.255.0");
-  ipv4.Assign (nd0);
+  Ipv4InterfaceContainer interfaces = ipv4.Assign (devices);
 
 //
 // Create an OnOff application to send UDP datagrams from node zero to node 1.
@@ -96,11 +91,11 @@
   uint16_t port = 9;   // Discard port (RFC 863)
 
   OnOffHelper onoff ("ns3::UdpSocketFactory", 
-    Address (InetSocketAddress (Ipv4Address ("10.1.1.2"), port)));
+                     Address (InetSocketAddress (interfaces.GetAddress (1), port)));
   onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
   onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
 
-  ApplicationContainer app = onoff.Install (c.Get (0));
+  ApplicationContainer app = onoff.Install (nodes.Get (0));
   // Start the application
   app.Start (Seconds (1.0));
   app.Stop (Seconds (10.0));
@@ -108,19 +103,21 @@
   // Create an optional packet sink to receive these packets
   PacketSinkHelper sink ("ns3::UdpSocketFactory",
     Address (InetSocketAddress (Ipv4Address::GetAny (), port)));
-  sink.Install (c.Get (1));
+  app = sink.Install (nodes.Get (1));
+  app.Start (Seconds (0.0));
 
 // 
 // Create a similar flow from n3 to n0, starting at time 1.1 seconds
 //
   onoff.SetAttribute ("Remote", 
-                      AddressValue (InetSocketAddress (Ipv4Address ("10.1.1.1"), port)));
-  ApplicationContainer app2 = onoff.Install (c.Get (3));
+                      AddressValue (InetSocketAddress (interfaces.GetAddress (0), port)));
+  app = onoff.Install (nodes.Get (3));
+  app.Start(Seconds (1.1));
+  app.Stop (Seconds (10.0));
 
-  sink.Install (c.Get (0));
+  app = sink.Install (nodes.Get (0));
+  app.Start (Seconds (0.0));
 
-  app2.Start(Seconds (1.1));
-  app2.Stop (Seconds (10.0));
 //
 // Configure tracing of all enqueue, dequeue, and NetDevice receive events.
 // Trace output will be sent to the file "csma-one-subnet.tr"
--- a/examples/simple-error-model.cc	Sat Sep 27 15:06:38 2008 +0100
+++ b/examples/simple-error-model.cc	Sat Sep 27 15:17:37 2008 +0100
@@ -134,7 +134,7 @@
   // Create an optional packet sink to receive these packets
   PacketSinkHelper sink ("ns3::UdpSocketFactory",
     Address (InetSocketAddress (Ipv4Address::GetAny (), port)));
-  apps = sink.Install (c.Get (3));
+  apps = sink.Install (c.Get (2));
   apps.Start (Seconds (1.0));
   apps.Stop (Seconds (10.0));
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/regression/tests/test-tcp-nsc-lfn.py	Sat Sep 27 15:17:37 2008 +0100
@@ -0,0 +1,33 @@
+#! /usr/bin/env python
+
+"""Trace-comparison-type regression test for the Network Simulation Cradle."""
+
+import os
+import shutil
+import sys
+import tracediff
+import platform
+
+
+def run(verbose, generate, refDirName):
+    """Run a Network Simulation Cradle test involving two TCP streams."""
+
+    if not tracediff.env['ENABLE_NSC']:
+        print >>sys.stderr, "Skipping tcp-nsc-lfn: NSC not available."
+        raise NotImplementedError
+
+    testName = "tcp-nsc-lfn"
+    arguments = ["--ns3::OnOffApplication::DataRate=40000", "--runtime=20"]
+    platform_bits = platform.architecture()[0]
+    
+    if platform_bits == "64bit":
+        traceDirName = testName + "_64bit.ref"
+    elif platform_bits == "32bit":
+        traceDirName = testName + "_32bit.ref"
+    else:
+        # Something unexpected. How should we signal an error here? Rasing a
+        # string might not be the best idea?
+        raise "Unknown architecture, not 64 or 32 bit?"
+
+    return tracediff.run_test(verbose, generate, refDirName,
+        testName, arguments=arguments, refTestName=traceDirName)
--- a/src/internet-stack/nsc-tcp-l4-protocol.cc	Sat Sep 27 15:06:38 2008 +0100
+++ b/src/internet-stack/nsc-tcp-l4-protocol.cc	Sat Sep 27 15:17:37 2008 +0100
@@ -39,8 +39,8 @@
 #include <dlfcn.h>
 #include <iomanip>
 
-#include <netinet/ip.h>
-#include <netinet/tcp.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
 
 NS_LOG_COMPONENT_DEFINE ("NscTcpL4Protocol");
 
@@ -82,17 +82,15 @@
 NscTcpL4Protocol::NscTcpL4Protocol ()
   : m_endPoints (new Ipv4EndPointDemux ()),
     m_nscStack (0),
-    m_nscInterfacesSetUp(false),
     m_softTimer (Timer::CANCEL_ON_DESTROY)
 {
   m_dlopenHandle = NULL;
-  NS_LOG_FUNCTION_NOARGS ();
   NS_LOG_LOGIC("Made a NscTcpL4Protocol "<<this);
 }
 
 NscTcpL4Protocol::~NscTcpL4Protocol ()
 {
-  NS_LOG_FUNCTION_NOARGS ();
+  NS_LOG_FUNCTION (this);
   dlclose(m_dlopenHandle);
 }
 
@@ -135,6 +133,10 @@
   node->AggregateObject (nscStack);
 
   m_softTimer.Schedule ();
+
+  // its likely no ns-3 interface exits at this point, so
+  // we dealy adding the nsc interface until the start of the simulation.
+  Simulator::ScheduleNow (&NscTcpL4Protocol::AddInterface, this);
 }
 
 int 
@@ -151,7 +153,7 @@
 void
 NscTcpL4Protocol::DoDispose (void)
 {
-  NS_LOG_FUNCTION_NOARGS ();
+  NS_LOG_FUNCTION (this);
   if (m_endPoints != 0)
     {
       delete m_endPoints;
@@ -164,59 +166,7 @@
 Ptr<Socket>
 NscTcpL4Protocol::CreateSocket (void)
 {
-  NS_LOG_FUNCTION_NOARGS ();
-  if (!m_nscInterfacesSetUp)
-  {
-    Ptr<Ipv4> ip = m_node->GetObject<Ipv4> ();
-
-    const uint32_t nInterfaces = ip->GetNInterfaces ();
-    // start from 1, ignore the loopback interface (HACK)
-
-    NS_ASSERT_MSG (nInterfaces <= 2, "nsc does not support multiple interfaces per node");
-
-    for (uint32_t i = 1; i < nInterfaces; i++)
-    {
-      Ipv4Address addr = ip->GetAddress(i);
-      Ipv4Mask mask = ip->GetNetworkMask(i);
-      uint16_t mtu = ip->GetMtu (i);
-
-      std::ostringstream addrOss, maskOss;
-
-      addr.Print(addrOss);
-      mask.Print(maskOss);
-
-      NS_LOG_LOGIC ("if_attach " << addrOss.str().c_str() << " " << maskOss.str().c_str() << " " << mtu);
-
-      std::string addrStr = addrOss.str();
-      std::string maskStr = maskOss.str();
-      const char* addrCStr = addrStr.c_str();
-      const char* maskCStr = maskStr.c_str();
-      m_nscStack->if_attach(addrCStr, maskCStr, mtu);
-
-      if (i == 1)
-      {
-        // We need to come up with a default gateway here. Can't guarantee this to be
-        // correct really...
-
-        uint8_t addrBytes[4];
-        addr.Serialize(addrBytes);
-
-        // XXX: this is all a bit of a horrible hack
-        //
-        // Just increment the last octet, this gives a decent chance of this being
-        // 'enough'.
-        //
-        // All we need is another address on the same network as the interface. This
-        // will force the stack to output the packet out of the network interface.
-        addrBytes[3]++;
-        addr.Deserialize(addrBytes);
-        addrOss.str("");
-        addr.Print(addrOss);
-        m_nscStack->add_default_gateway(addrOss.str().c_str());
-      }
-    }
-    m_nscInterfacesSetUp = true;
-  }
+  NS_LOG_FUNCTION (this);
 
   Ptr<RttEstimator> rtt = m_rttFactory.Create<RttEstimator> ();
   Ptr<NscTcpSocketImpl> socket = CreateObject<NscTcpSocketImpl> ();
@@ -229,7 +179,7 @@
 Ipv4EndPoint *
 NscTcpL4Protocol::Allocate (void)
 {
-  NS_LOG_FUNCTION_NOARGS ();
+  NS_LOG_FUNCTION (this);
   return m_endPoints->Allocate ();
 }
 
@@ -305,7 +255,6 @@
 
 void NscTcpL4Protocol::SoftInterrupt (void)
 {
-  NS_LOG_FUNCTION_NOARGS ();
   m_nscStack->timer_interrupt ();
   m_nscStack->increment_ticks ();
   m_softTimer.Schedule ();
@@ -314,27 +263,31 @@
 void NscTcpL4Protocol::send_callback(const void* data, int datalen)
 {
   Ptr<Packet> p;
-
-  NS_ASSERT(datalen > (int)sizeof(struct iphdr));
+  uint32_t ipv4Saddr, ipv4Daddr;
 
-  const uint8_t *rawdata = reinterpret_cast<const uint8_t *>(data);
-  rawdata += sizeof(struct iphdr);
+  NS_ASSERT(datalen > 20);
 
-  const struct iphdr *ipHdr = reinterpret_cast<const struct iphdr *>(data);
 
   // create packet, without IP header. The TCP header is not touched.
   // Not using the IP header makes integration easier, but it destroys
   // eg. ECN.
-  p = Create<Packet> (rawdata, datalen - sizeof(struct iphdr));
+  const uint8_t *rawdata = reinterpret_cast<const uint8_t *>(data);
+  rawdata += 20; // skip IP header. IP options aren't supported at this time.
+  datalen -= 20;
+  p = Create<Packet> (rawdata, datalen);
 
-  Ipv4Address saddr(ntohl(ipHdr->saddr));
-  Ipv4Address daddr(ntohl(ipHdr->daddr));
+  // we need the real source/destination ipv4 addresses for Send ().
+  const uint32_t *ipheader = reinterpret_cast<const uint32_t *>(data);
+  ipv4Saddr = *(ipheader+3);
+  ipv4Daddr = *(ipheader+4);
+
+  Ipv4Address saddr(ntohl(ipv4Saddr));
+  Ipv4Address daddr(ntohl(ipv4Daddr));
 
   Ptr<Ipv4L3Protocol> ipv4 = m_node->GetObject<Ipv4L3Protocol> ();
-  if (ipv4 != 0)
-    {
-      ipv4->Send (p, saddr, daddr, PROT_NUMBER);
-    }
+  NS_ASSERT_MSG (ipv4, "nsc callback invoked, but node has no ipv4 object");
+
+  ipv4->Send (p, saddr, daddr, PROT_NUMBER);
   m_nscStack->if_send_finish(0);
 }
 
@@ -364,5 +317,58 @@
 }
 
 
+void NscTcpL4Protocol::AddInterface(void)
+{
+  Ptr<Ipv4> ip = m_node->GetObject<Ipv4> ();
+  const uint32_t nInterfaces = ip->GetNInterfaces ();
+
+  NS_ASSERT_MSG (nInterfaces <= 2, "nsc does not support multiple interfaces per node");
+
+  // start from 1, ignore the loopback interface (HACK)
+  // we really don't need the loop, but its here to illustrate
+  // how things _should_ be (once nsc can deal with multiple interfaces...)
+  for (uint32_t i = 1; i < nInterfaces; i++)
+    {
+      Ipv4Address addr = ip->GetAddress(i);
+      Ipv4Mask mask = ip->GetNetworkMask(i);
+      uint16_t mtu = ip->GetMtu (i);
+
+      std::ostringstream addrOss, maskOss;
+
+      addr.Print(addrOss);
+      mask.Print(maskOss);
+
+      NS_LOG_LOGIC ("if_attach " << addrOss.str().c_str() << " " << maskOss.str().c_str() << " " << mtu);
+
+      std::string addrStr = addrOss.str();
+      std::string maskStr = maskOss.str();
+      const char* addrCStr = addrStr.c_str();
+      const char* maskCStr = maskStr.c_str();
+      m_nscStack->if_attach(addrCStr, maskCStr, mtu);
+
+      if (i == 1)
+      {
+        // We need to come up with a default gateway here. Can't guarantee this to be
+        // correct really...
+
+        uint8_t addrBytes[4];
+        addr.Serialize(addrBytes);
+
+        // XXX: this is all a bit of a horrible hack
+        //
+        // Just increment the last octet, this gives a decent chance of this being
+        // 'enough'.
+        //
+        // All we need is another address on the same network as the interface. This
+        // will force the stack to output the packet out of the network interface.
+        addrBytes[3]++;
+        addr.Deserialize(addrBytes);
+        addrOss.str("");
+        addr.Print(addrOss);
+        m_nscStack->add_default_gateway(addrOss.str().c_str());
+      }
+  }
+}
+
 }; // namespace ns3
 
--- a/src/internet-stack/nsc-tcp-l4-protocol.h	Sat Sep 27 15:06:38 2008 +0100
+++ b/src/internet-stack/nsc-tcp-l4-protocol.h	Sat Sep 27 15:17:37 2008 +0100
@@ -109,12 +109,12 @@
   Ipv4EndPointDemux *m_endPoints;
   ObjectFactory m_rttFactory;
 private:
+  void AddInterface (void);
   void SoftInterrupt (void);
   static ObjectFactory GetDefaultRttEstimatorFactory (void);
   friend class NscTcpSocketImpl;
   INetStack* m_nscStack;
   void *m_dlopenHandle;
-  bool m_nscInterfacesSetUp;
   Timer m_softTimer;
 };
 
--- a/src/internet-stack/nsc-tcp-socket-impl.cc	Sat Sep 27 15:06:38 2008 +0100
+++ b/src/internet-stack/nsc-tcp-socket-impl.cc	Sat Sep 27 15:17:37 2008 +0100
@@ -33,11 +33,9 @@
 
 #include <algorithm>
 
-#include <sys/socket.h>
-#include <netinet/in.h>
+// for ntohs().
 #include <arpa/inet.h>
-#include <netinet/ip.h>
-#include <netinet/tcp.h>
+#include <netinet/in.h>
 
 #include "sim_interface.h"
 #include "sim_errno.h"
@@ -307,13 +305,11 @@
   m_remoteAddress = transport.GetIpv4 ();
   m_remotePort = transport.GetPort ();
 
-  struct in_addr remoteAddr;
-  uint32_t addr32;
+  std::ostringstream ss;
+  m_remoteAddress.Print(ss);
+  std::string ipstring = ss.str ();
 
-  m_remoteAddress.Serialize((uint8_t*)&addr32);
-  remoteAddr.s_addr = addr32;
-
-  m_nscTcpSocket->connect(inet_ntoa(remoteAddr), m_remotePort);
+  m_nscTcpSocket->connect(ipstring.c_str (), m_remotePort);
   m_state = SYN_SENT;
   return 0;
 }
--- a/src/internet-stack/udp-socket-impl.cc	Sat Sep 27 15:06:38 2008 +0100
+++ b/src/internet-stack/udp-socket-impl.cc	Sat Sep 27 15:17:37 2008 +0100
@@ -30,6 +30,7 @@
 #include "udp-socket-impl.h"
 #include "udp-l4-protocol.h"
 #include "ipv4-end-point.h"
+#include <limits>
 
 NS_LOG_COMPONENT_DEFINE ("UdpSocketImpl");
 
--- a/src/internet-stack/wscript	Sat Sep 27 15:06:38 2008 +0100
+++ b/src/internet-stack/wscript	Sat Sep 27 15:17:37 2008 +0100
@@ -54,6 +54,8 @@
         nsc_update()
 
 def configure(conf):
+    conf.env['ENABLE_NSC'] = False
+
     # checks for flex and bison, which is needed to build NSCs globaliser
     def check_nsc_buildutils():
         import flex
@@ -82,6 +84,7 @@
         e.define = 'HAVE_DL'
         e.uselib = 'DL'
         e.run()
+        conf.env['ENABLE_NSC'] = True
         ok = True
     conf.check_message('NSC supported architecture', arch, ok)
     conf.report_optional_feature("nsc", "Network Simulation Cradle", ok,
--- a/wscript	Sat Sep 27 15:06:38 2008 +0100
+++ b/wscript	Sat Sep 27 15:17:37 2008 +0100
@@ -820,7 +820,7 @@
         self.testdir = testdir
         self.env = Params.g_build.env_of_name('default')
 
-    def run_test(self, verbose, generate, refDirName, testName, arguments=[], pyscript=None):
+    def run_test(self, verbose, generate, refDirName, testName, arguments=[], pyscript=None, refTestName=None):
         """
         @param verbose: enable verbose execution
 
@@ -836,11 +836,17 @@
         parameter contains the path to the python script, relative to
         the project root dir
 
+        @param refTestName: if not None, this is the name of the directory under refDirName
+        that contains the reference traces. Otherwise "refDirname/testName + .ref" is used.
+
         """
         if not isinstance(arguments, list):
             raise TypeError
         
-        refTestDirName = os.path.join(refDirName, (testName + ".ref"))
+        if refTestName is None:
+            refTestDirName = os.path.join(refDirName, (testName + ".ref"))
+        else:
+            refTestDirName = os.path.join(refDirName, refTestName)
 
         if not os.path.exists(refDirName):
             print"No reference trace repository"