put updated tutorial.texi in doc directory
authorCraig Dowell <craigdo@ee.washington.edu>
Thu, 13 Dec 2007 23:50:16 -0800
changeset 2187 d13161eb95df
parent 2186 69ad6ed6ccf4
child 2188 36d410f015bf
put updated tutorial.texi in doc directory
doc/tutorial/dumbbell.png
doc/tutorial/pp.png
doc/tutorial/star.png
doc/tutorial/tutorial.texi
Binary file doc/tutorial/dumbbell.png has changed
Binary file doc/tutorial/pp.png has changed
Binary file doc/tutorial/star.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/tutorial/tutorial.texi	Thu Dec 13 23:50:16 2007 -0800
@@ -0,0 +1,3498 @@
+\input texinfo  @c -*-texinfo-*-
+@c %**start of header
+@setfilename ns-3.info
+@settitle ns-3 tutorial
+@c @setchapternewpage odd
+@c %**end of header
+
+@ifinfo
+This @command{ns-3} project document is one of a set of project documents:
+@itemize @bullet
+@item Software Architecture 
+@item Manual 
+@item Tutorial (this document)
+@end itemize
+ 
+This document is written in GNU Texinfo and is to be maintained in
+revision control on the @command{ns-3} code server.  Both PDF and HTML versions
+should be available on the server.  Changes to 
+the document should be discussed on the ns-developers@@isi.edu mailing list.
+@end ifinfo
+
+@copying
+This @command{ns-3} project document is one of a set of project documents:
+@itemize @bullet
+@item Software Architecture 
+@item Manual 
+@item Tutorial (this document)
+@end itemize
+ 
+This document is written in GNU Texinfo and is to be maintained in
+revision control on the @command{ns-3} code server.  Both PDF and HTML 
+versions should be available on the server.  Changes to 
+the document should be discussed on the ns-developers@@isi.edu mailing list.
+
+This software 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 2 of the License, or
+(at your option) any later version.
+
+This software 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, see @uref{http://www.gnu.org/licenses/}.
+@end copying
+
+@titlepage
+@title ns-3 Tutorial
+@author ns-3 project
+@author feedback:  ns-developers@@isi.edu
+@today{}
+
+@c @page
+@vskip 0pt plus 1filll
+@insertcopying
+@end titlepage
+
+@c So the toc is printed at the start.
+@anchor{Full Table of Contents}
+@contents
+
+@ifnottex
+@node Top, Preface, Full Table of Contents 
+@top ns-3 Tutorial (html version)
+
+For a pdf version of this manual, 
+see @uref{http://www.nsnam.org/docs/tutorial.pdf}.
+
+@insertcopying
+@end ifnottex
+
+@menu
+* Preface::
+* Introduction::
+* Resources::
+* The-Basics::
+* Some-Prerequisites::
+* A-First-ns-3-Script::
+* Tracing-at-a-Glance::
+* Other-network-topologies::
+* Nonlinear-Thinking::
+* Summary::
+* The-Doxygen-Documentation-System::
+* How-To-Change-Things::
+* How-To-Set-Default-Values::
+* How-To-Write-A-New-Application::
+@end menu
+
+@node Preface
+@chapter Preface
+
+The purpose of this tutorial is to introduce new @command{ns-3} users to the 
+system in a structured way.  It is sometimes difficult for new users to
+glean essential information from detailed manuals and to convert this
+information into working simulations.  In this tutorial, we will build 
+several example simulations, introducing and explaining key concepts and
+features as we go.
+
+As the tutorial unfolds, we will introduce the full @command{ns-3} 
+documentation 
+and provide pointers to source code for those interested in delving deeper
+into the workings of the system.
+
+This document is one of a set of @command{ns-3} project documents:
+@itemize @bullet
+@item Software Architecture 
+@item Manual 
+@item Tutorial (this document)
+@end itemize
+ 
+This document is written in Texinfo and is to be maintained in
+revision control on the @command{ns-3} code server.  Both PDF and HTML versions
+should be available on the server.  Changes to 
+the document should be discussed on the ns-developers@@isi.edu mailing list.
+  
+@c ========================================================================
+@c Begin document body here
+@c ========================================================================
+
+@c ========================================================================
+@c Introduction
+@c ========================================================================
+
+@node Introduction
+@chapter Introduction
+
+The @command{ns-3} project is a discrete-event network simulator targeted
+primarily for research and educational use.  It is aimed at 
+comprehensively redesigning and enhancing the popular Network Simulator 
+@command{ns-2}.
+
+For those familiar with @command{ns-2}, the most visible outward change 
+when moving to @command{ns-3} is the choice of scripting language.  
+@command{ns-2} is typically scripted in Tcl and results of simulations are
+often visualized using the Network Animator @command{nam}.  In 
+@command{ns-3} there is currently no visualization module, and multiple 
+language bindings are allowed.  In this tutorial, we will concentrate on 
+scripting directly in C++ and interpreting results via trace files.  Scripting
+in other languages will typically be done via straightforward bindings of the 
+target language into the underlying C++.
+
+The goal of this tutorial is to introduce new users of @command{ns-3} to enough
+of the system to enable them to author simple simulation scripts and extract
+useful information from the simulations.  We begin by introducing some of the
+other important resources that are available to those interested in using or
+writing scripts, models and even those interested in making contributions to
+the core @command{ns-3} system.  We provide an overview of some of the 
+important abstractions, design patterns and idioms used when writing 
+@command{ns-3} scripts, and then dig right in by begining to write simulation 
+scripts, run them and interpret results.
+
+After completing this tutorial, one should be able to:
+@itemize @bullet
+@item Find documentation resources in the distribution and on the web;
+@item Download and compile the @command{ns-3} system;
+@item Use the provided devices to author network simulations of fairly  
+significant complexity;
+@item Use the default value system to configure simulations;
+@item Write new @command{ns-3} applications;
+@item Use the tracing subsystem.
+@end itemize
+
+@c ========================================================================
+@c Resources
+@c ========================================================================
+
+@node Resources
+@chapter Resources
+
+@menu
+* The-Web::
+* Mercurial::
+* Waf::
+* Environment-Idioms-Design-Patterns::
+* Socket-Programming::
+@end menu
+
+@node The-Web
+@section The Web
+
+@cindex www.nsnam.org
+There are several important resources of which any @command{ns-3} user must be
+aware.  The main web site is located at @uref{http://www.nsnam.org}
+and provides access to basic information about the @command{ns-3} system.  
+Detailed documentation is available through the main web site at
+@uref{http://www.nsnam.org/documents.html}.
+
+@cindex documentation
+@cindex architecture
+You can find documents relating to the system architecture from this page,
+and also gain access to the detailed software documentation.  The software
+system is documented in great detail using 
+@uref{http://www.stack.nl/~dimitri/doxygen/,,Doxygen}.  There is a Wiki that
+complements the main @command{ns-3} web site which you will find at 
+@uref{http://www.nsnam.org/wiki/}.
+
+You will find user and developer FAQs there as well as troubleshooting guides, 
+third-party contributed code, papers, etc. The source code may be found 
+and browsed at @uref{http://code.nsnam.org/}. 
+
+@cindex repository!ns-3-dev
+@cindex repository!releases
+There you will find the current development tree in the repository named
+@code{ns-3-dev}. Past releases and experimental repositories of the core
+developers may also be found there.
+
+@node Mercurial
+@section Mercurial
+
+Complex software systems need some way to manage the organization and 
+changes to the underlying code and documentation.  There are many ways to
+perform this feat, and you may have heard of some of the systems that are
+currently used to do this.  The Concurrent Version System (CVS) is probably
+the most well known.
+
+@cindex software configuration management
+@cindex Mercurial
+The @command{ns-3} project uses Mercurial as its source code management system.
+Although you do not need to know much about Mercurial in order to complete
+this tutorial, we recommend becoming familiar with Mercurial and using it 
+to access the source code.  Mercurial has a web site at 
+@uref{http://www.selenic.com/mercurial/},
+from which you can get binary or source releases of this Software
+Configuration Management (SCM) system.  Selenic (the developer of Mercurial)
+also provides a tutorial at 
+@uref{http://www.selenic.com/mercurial/wiki/index.cgi/Tutorial/},
+and a QuickStart guide at
+@uref{http://www.selenic.com/mercurial/wiki/index.cgi/QuickStart/}.
+
+You can also find vital information about using Mercurial and @command{ns-3}
+on the main @command{ns-3} web site.
+
+@node Waf
+@section Waf
+
+@cindex Waf
+@cindex make
+@cindex build
+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 famous of these tools is @code{make}.  Along
+with being the most famous, @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
+using the Python language.
+
+The build system @code{Waf} is used on the @command{ns-3} project.  It is one 
+of the new generation of Python-based build systems.  You will not need to 
+understand any Python to build the existing @command{ns-3} system, and will 
+only have to understand a tiny and intuitively obvious subset of Python in 
+order to extend the system in most cases.
+
+For those interested in the gory details of Waf, the main web site can be 
+found at @uref{http://freehackers.org/\~tnagy/waf.html}.
+
+@node Environment-Idioms-Design-Patterns
+@section Environment, Idioms, and Design Patterns
+
+@cindex C++
+As mentioned above, scripting in @command{ns-3} is done in C++.  A working 
+knowledge of C++ and object-oriented concepts is assumed in this document.
+We will take some time to review some of the more advanced concepts or 
+possibly unfamiliar language features, idioms and design patterns as they 
+appear.  We don't want this tutorial to devolve into a C++ tutorial, though,
+so we do expect a basic command of the language.  There are an almost 
+unimaginable number of sources of information on C++ available on the web or
+in print.
+
+If you are new to C++, you may want to find a tutorial- or cookbook-based
+book or web site and work through at least the basic features of the language
+before proceeding.
+
+@subsection Environment
+
+@cindex toolchain
+@cindex GNU
+The @command{ns-3} system uses the GNU ``toolchain'' for development.  
+A software toolchain is the set of programming tools available in the given 
+environment. For a quick review of what is included in the GNU toolchain see,
+@uref{http://en.wikipedia.org/wiki/GNU_toolchain}.
+
+@cindex Linux
+Typically a @command{ns-3} author will work in Linux or a Linux-like
+environment.  For those running under Windows, there do exist environments 
+which simulate the Linux environment to various degrees.  The @command{ns-3} 
+project supports development in the Cygwin and the MinGW environments for 
+these users.  See @uref{http://www.cygwin.com/} and 
+@uref{http://www.mingw.org/} for details on downloading and using these
+systems.  I use Cygwin in these cases since it provides all of the Linux tools
+I know and love.  It can, however, sometimes be problematic due to the way it 
+actually does its emulation, and sometimes interactions with other Windows
+software can cause problems.
+
+@cindex Cygwin
+@cindex MinGW
+If you do use Cygwin or MinGW; and use Logitech products, I will save you
+quite a bit of heartburn right off the bat and encourage you to take a look
+at the @uref{http://www.mingw.org/MinGWiki/index.php/FAQ,,MinGW FAQ}.
+
+@cindex Logitech
+Search for ``Logitech'' and read the FAQ entry, ``why does make often 
+crash creating a sh.exe.stackdump file when I try to compile my source code.''
+Believe it or not, the @code{Logitech Process Monitor} insinuates itself into
+every DLL in the system when it is running.  It can cause your Cygwin or
+MinGW DLLs to die in mysterious ways and often prevents debuggers from 
+running.  Beware of Logitech.
+
+@subsection Idioms and Design Patterns
+
+@cindex idiom
+In any system, there are a number of problems to be solved that happen 
+repeatedly.  Often the solutions to these problems can be generalized and
+applied in a similar way across the system.  These solutions are called
+Design Patterns.  The @command{ns-3} system relies on several classic design
+patterns.
+
+@cindex design pattern
+Also, in any language, there are constructs that, while they aren't part of the
+language per se, are commonly found and useful.  For example, at the lowest 
+level a C programmer should be able to immediately recognize the purpose and 
+intent  of the following code without having to reflect on the details:
+
+@verbatim
+  for (;;)
+@end verbatim
+
+These low-level constructs, or idioms, extend upward in complexity, eventually
+becoming implementations of design patterns.  As you are exposed to more 
+and more of the @command{ns-3} system, you will begin to recognize and be 
+comfortable with the C++ implementations (idioms) of several important design
+patterns.
+
+@cindex functor
+@cindex callback
+@cindex smart pointer
+The @command{ns-3} code relies heavily on 
+@emph{Generalized Functors, Callbacks, 
+Smart Pointers, Singletons, and Object Factories}.  Although we will 
+not assume any detailed knowledge of the idioms and design patterns used 
+in the @command{ns-3}
+system, it will be useful for readers who intend to delve deeply into the
+system to understand some important related concepts.  We recommend two 
+resources: @uref{http://www.amazon.com/Design-Patterns-Object-Oriented-Addison-Wesley-Professional/dp/0201633612/,,Design Patterns: Elements of Reusable Object-Oriented Software, Gamma et. al.} and
+@uref{http://www.amazon.com/exec/obidos/ASIN/0201704315,,Modern C++ Design: Generic Programming and Design Patterns Applied, Alexandrescu}.
+
+Gamma addresses the abstract design patterns, and Alexandrescu addresses the
+C++ idioms you will often see throughout the @command{ns-3} code.
+
+@cindex template
+Almost any use of @command{ns-3} will require some basic knowledge of C++ 
+templates.
+We will discuss the high-level uses in this tutorial.  However, if you venture
+deeply into the source code, you will see fairly heavy use of relatively
+sophisticated C++ templates in some of low-level modules of the system.  The
+You don't have to be a template guru to complete this tutorial but if you
+expect to work in @command{ns-3} at a low level you will have to be 
+somewhat fluent
+with templates.  If you  want to truly grok C++ templates we recommend,
+@uref{http://www.amazon.com/Templates-Complete-Guide-David-Vandevoorde/dp/0201734842/,,C++ Templates: The Complete Guide, Vandevoorde and Josuttis}.
+
+@node Socket-Programming
+@section Socket Programming
+
+@cindex sockets
+We will assume a basic facility with the Berkeley Sockets API in the examples
+used in this tutorial.  If you are new to sockets, we recommend reviewing the
+API and some common usage cases.  For a good overview of programming TCP/IP
+sockets we recommend @uref{http://www.elsevier.com/wps/product/cws_home/680765,,Practical TCP/IP Sockets in C, Donahoo and Calvert}.
+
+There is an associated web site that includes source for the examples in the
+book, which you can find at:
+@uref{http://cs.baylor.edu/~donahoo/practical/CSockets/}.
+
+If you understand the first four chapters of the book (or for those who do
+not have access to a copy of the book, the echo clients and servers shown in 
+the website above) you will be in good shape to understand the tutorial.
+There is a similar book on Multicast Sockets,
+@uref{http://www.elsevier.com/wps/product/cws_home/700736,,Multicast Sockets, Makofske and Almeroth}.
+that covers material you may need to understand for the multicast examples.
+
+@c ========================================================================
+@c The Basics
+@c ========================================================================
+
+@node The-Basics
+@chapter The Basics
+
+@cindex Linux
+@cindex Cygwin
+@cindex GNU
+@cindex toolchain
+From this point forward, we are going to assume that the reader is working in
+Linux or a Linux emulation environment (Linux, Cygwin, etc.) and has the GNU
+toolchain installed and verified.  
+
+@cindex Mercurial
+@cindex Waf
+We are going to assume that you have Mercurial and Waf installed and running
+on the target system as described in the Getting Started section of the 
+@command{ns-3} web site: @uref{http://www.nsnam.org/getting_started.html}.
+
+@section Downloading
+@cindex tarball
+The @command{ns-3} code is available in Mercurial repositories on the server
+code.nsnam.org.  You can download a tarball, but we recommend working with
+Mercurial -- it will make your life easier in the long run.
+
+@cindex repository
+If you go to the following link: @uref{http://code.nsnam.org/},
+you will see a number of repositories.  Many are the private repositories of
+the @command{ns-3} development team.  The repositories of interest to you 
+will be
+prefixed with ``ns-3''.  The current development snapshot (unreleased) of
+@command{ns-3} may be found at: @uref{http://code.nsnam.org/ns-3-dev/}.
+
+The developers attempt to keep this repository in a consistent, working state
+but it is a development area with unreleased code present, so you may want to
+consider downloading an official release.
+
+There will be a number of released repositories present at code.nsnam.org.
+These repos will have names like ns-3.0.1 -- which referes to release 3.0.1 
+of the network simulator (or if you like, release 0.1 of @command{ns-3}).  
+Since the releases are changing at a rate of one per month, I will stick with 
+the more constant ns-3-dev here, but you can replace the string ns-3-dev with
+your choice of release (e.g., ns-3.0.5) below.  You can find the latest 
+version  of the code either by inspection of the repository list or by going 
+to the ``Getting Started'' web page and looking for the latest release 
+identifier.
+
+I typically create a directory called @code{repos} in my home directory under
+which I keep all of my local Mercurial repositories.  @emph{Hint:  I will
+assume you do this later in the tutorial.} If you adopt that approach, you 
+can get a copy of the development version of @command{ns-3} by typing 
+the following into your Linux shell (I use bash).
+
+@verbatim
+  cd
+  mkdir repos
+  cd !$
+  hg clone http://code.nanam.org/ns-3-dev
+@end verbatim
+
+As the hg command executes, you should see something like the following,
+
+@verbatim
+  destination directory: ns-3-dev
+  requesting all changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1513 changesets with 5687 changes to 733 files
+  358 files updated, 0 files merged, 0 files removed, 0 files unresolved
+@end verbatim
+
+After the clone command completes, you should have a directory called 
+ns-3-dev under your @code{~/repos} directory, the contents of which should 
+look something like the following:
+
+@verbatim
+  AUTHORS  RELEASE_NOTES  examples/  src/       waf*
+  LICENSE  VERSION        ns3/       tutorial/  waf.bat*
+  README   doc/           samples/   utils/     wscript
+@end verbatim
+
+You are now ready to build the @command{ns-3} distribution.
+
+@section Building
+@cindex Waf!build
+@cindex Waf!configure
+@cindex Waf!debug
+@cindex Waf!compile
+We use Waf to build the @command{ns-3} project.  The first thing you 
+will need to do is to configure the build.  For reasons that will become clear
+later, we are going to work with debug builds in the tutorial.  To explain to 
+Waf that it should do debug builds you will need to execute the following 
+command,
+
+@verbatim
+  ./waf -d debug configure
+@end verbatim
+
+This runs the copy of Waf in the local directory (which is provided as a 
+convenience for you).  As the build system checks for various dependencies
+you should see output that looks similar to the following,
+
+@verbatim
+  ~/repos/ns-3-dev >./waf -d debug configure
+  Checking for program g++                : ok /usr/bin/g++
+  Checking for program cpp                : ok /usr/bin/cpp
+  Checking for program ar                 : ok /usr/bin/ar
+  Checking for program ranlib             : ok /usr/bin/ranlib
+  Checking for compiler could create programs : ok
+  Checking for compiler could create shared libs : ok
+  Checking for compiler could create static libs : ok
+  Checking for flags -Wall                       : ok
+  Checking for flags -O2                         : ok
+  Checking for flags -g -DDEBUG                  : ok
+  Checking for flags -g3 -O0 -DDEBUG             : ok
+  Checking for g++                               : ok
+  Checking for header stdlib.h                   : ok
+  Checking for header stdlib.h                   : ok
+  Checking for header signal.h                   : ok
+  Checking for high precision time implementation: 128-bit integer
+  Checking for header stdint.h                   : ok
+  Checking for header inttypes.h                 : ok
+  Checking for header sys/inttypes.h             : not found
+  Configuration finished successfully; project is now ready to build.
+  ~/repos/ns-3-dev >
+@end verbatim
+
+The build system is now configured and you can build the debug versions of 
+the @command{ns-3} programs by simply typing,
+
+@verbatim
+  ./waf
+@end verbatim
+
+You will see many Waf status messages displayed as the system compiles.  The
+most important is the last one,
+
+@verbatim
+  Compilation finished successfully
+@end verbatim
+
+@section Running a Script
+@cindex Waf!run
+We typically run scripts under the control of Waf.  This allows the build 
+system to ensure that the shared library paths are set correctly and that
+the libraries are available at run time.  To run a program, simply use the
+@code{run} option in Waf.  Let's run the @command{ns-3} equivalent of the hello
+world program by typing the following:
+
+@verbatim
+  ./waf --run hello-simulator
+@end verbatim
+
+Waf first checks to make sure that the program is built correctly and 
+executes a build if required.  Waf then then executes the program, which 
+produces the following output.
+
+@verbatim
+  Hello Simulator
+@end verbatim
+
+@emph{Congratulations.  You are now an @command{ns-3} user.}
+
+@c ========================================================================
+@c Some Prerequisites
+@c ========================================================================
+
+@node Some-Prerequisites
+@chapter Some Prerequisites
+
+The first thing we need to do before actually starting to code is to explain
+a few core concepts, abstractions and idioms in the system.  Much of this may
+appear transparently obvious to some, but we recommend taking the time to read
+through this chapter just to ensure you are starting on a firm foundation.
+
+@section Abstractions
+
+In this section, we'll review some terms that are commonly used in
+networking, but have a specific meaning in @command{ns-3}.
+
+@subsection Node
+@cindex Node
+In Internet jargon, a computing device that connects to a network is called
+a @emph{host} or sometimes an @emph{end system}.  Because @command{ns-3} is a 
+@emph{network} simulator, not specifically an @emph{Internet} simulator, we 
+intentionally do not use the term host since it is closely associated with
+the Internet and its protocols.  Instead, we use a more generic term also
+used by other simulators that originates in Graph Theory -- the @emph{node}.
+
+@cindex Node!class
+In @command{ns-3} the basic computing device abstraction is called the 
+node.  This abstraction is represented in C++ by the class @code{Node}.  The 
+@code{Node} class provides methods for managing the representations of 
+computing devices in simulations.  Developers are expected to specialize the 
+@code{Node} in the object-oriented programming sense to create new computing
+device models.  In this tutorial, we will use a specialization of class 
+@code{Node} called @code{InternetNode}.  As you might expect, the
+@code{InternetNode} is a class that represents a host in the Internet sense,
+and automatically provides core IPv4 networking protocols.
+
+You should think of a @code{Node} as a computer to which you will add 
+functionality.  One adds things like applications, protocol stacks and
+peripheral cards with their associated drivers to enable the computer to do
+useful work.  We use the same basic model in @command{ns-3}.
+
+@subsection Application
+@cindex Application
+Typically, computer software is divided into two broad classes.  @emph{System
+Software} organizes various computer resources such as memory, processor
+cycles, disk, network, etc., according to some computing model.  System
+software usually does not use those resources to complete tasks that directly
+benefit a user.  A user would typically run an @emph{application} that acquires
+and uses the resources controlled by the system software to accomplish some
+goal.  
+
+@cindex system call
+Often, the line of separation between system and application software is made
+at the privilege level change that happens in operating system traps.
+In @command{ns-3} there is no real concept of operating system and especially
+no concept of privilege levels or system calls.  We do, however, have the
+idea of an application.  Just as software applications run on computers to
+perform tasks in the ``real world,'' @command{ns-3} applications run on
+@command{ns-3} @code{Node}s to drive simulations in the simulated world.
+
+@cindex Application!class
+In @command{ns-3} the basic abstraction for a user program that generates some
+activity to be simulated is the application.  This abstraction is represented 
+in C++ by the class @code{Application}.  The @code{Application} class provides 
+methods for managing the representations of our version of user-level 
+applications in simulations.  Developers are expected to specialize the
+@code{Application} in the object-oriented programming sense to create new
+applications.  In this tutorial, we will use specializations of class 
+@code{Application} called @code{UdpEchoClient} and @code{UdpEchoServer}.
+As you might expect, these applications compose a client/server application set
+used to generate and echo simulated network packets 
+
+@subsection Channel
+@cindex Channel
+
+In the real world, one can connect a computer to a network.  Often the media
+over which data flows in these netowrks are called @emph{channels}.  When
+you connect your Ethernet cable to the plug in the wall, you are connecting 
+your computer to an Ethernet communication channel.  In the simulated world
+of @command{ns-3} one connects a @code{Node} to an object representing a
+communication channel.  Here the basic communication subnetwork abstraction 
+is called the channel and is represented in C++ by the class @code{Channel}.  
+
+The @code{Channel} class provides methods for managing communication 
+subnetwork objects and connecting nodes to them.  They may also be specialized
+by developers in the object oriented programming sense.  A @code{Channel}
+specialization may model something as simple as a wire.  The specialized 
+@code{Channel} can also model things as complicated as a large Ethernet
+switch, or three-dimensional space in the case of wireless networks.
+
+We will use specialized versions of the @code{Channel} called
+@code{CsmaChannel} and @code{PointToPointChannel} in this tutorial.  The
+@code{CsmaChannel}, for example, models a version of a communication subnetwork
+that implements a @emph{carrier sense multiple access} communication medium.
+This gives us Ethernet-like functionality.  
+
+@subsection Net Device
+@cindex NetDevice
+@cindex Ethernet
+
+It used to be the case that if you wanted to connect a computers to a network,
+you had to buy a specific kind of network cable and a hardware device called
+(in PC terminology) a @emph{peripheral card} that needed to be installed in
+your computer.  These cards were called Network Interface Cards, or 
+@emph{NIC}s.  Today most computers come with the network controller hardware
+built in and users don't see these building blocks.
+
+A NIC will not work without a software driver to control the hardware.  In 
+Unix (or Linux), a piece of peripheral hardware is classified as a 
+@emph{device}.  Devices are controlled using @emph{device drivers}, and network
+devices (NICs) are controlled using @emph{network device drivers}
+collectively known as @emph{net devices}.  In Unix and Linux you refer
+to these net devices by names such as @emph{eth0}.
+
+In @command{ns-3} the @emph{net device} abstraction covers both the software 
+driver and the simulated hardware.  A net device is ``attached'' to a 
+@code{Node} in order to enable the @code{Node} to communicate with other 
+@code{Node}s in the simulation via @code{Channel}s.  Just as in a real
+computer, a @code{Node} may be connected to more than one @code{Channel} via
+multiple @code{NetDevice}s.
+
+The net device abstraction is represented in C++ by the class @code{NetDevice}.
+The @code{NetDevice} class provides methods for managing connections to 
+@code{Node} and @code{Channel} objects; and may be specialized by developers
+in the object-oriented programming sense.  We will use the specialized version
+of the @code{NetDevice} called the @code{CsmaNetDevice} in this tutorial.
+Just as an Ethernet NIC is designed to work with an Ethernet network, the
+@code{CsmaNetDevice} is designed to work with a @code{CsmaChannel}.
+
+@subsection Topology Helpers
+In a real network, you will find host computers with added (or built-in)
+NICs.  In @command{ns-3} we would say that you will find @code{Nodes} with 
+attached @code{NetDevices}.  In a large simulated network you will need to 
+arrange many connections between @code{Node}s, @code{NetDevice}s and 
+@code{Channel}s.
+
+Since connecting a @code{NetDevice} to a @code{Node}, and a @code{NetDevice}
+to a @code{Channel} is such a common task in @command{ns-3} we provide what we
+call @emph{topology helpers} to make this as easy as possible.  Topology 
+helpers perform much of the dirty work of creating and connecting net devices.
+For example, it may take several distinct method calls to create a NetDevice,
+add a MAC address, connect the net device to a @code{Node} and configure
+the protocol stack, and then connect the @code{NetDevice} to a @code{Channel}.
+We use topology helper functions to compose those distinct operations into
+an easy to use model.
+
+Topology helper functions use the abstractions (described above) of Network
+Interface Cards and Cables.  When you think of adding a new kind of network,
+you may think of going out to the local computer retailer and buying a kit.
+This kit might include a nework cable and some number of peripheral cards and
+thier associated software drivers.  You can think of topology helpers in 
+roughly the same way.  Instead of buying a kit for a given type of network,
+you will use a topology helper class for a given type of network, to accomplish
+the equivalent of installing the network ``kit.''
+
+@section Important Idioms
+Now that we have identified that there are C++ classes in the system called
+@code{Node} and @code{InternetNode}, we need to understand how to bring
+objects of these classes into existance, and manage their lifetimes.  Let's
+examine this in some detail here.
+
+@cindex InternetNode
+@cindex Create
+@cindex Ptr
+In @command{ns-3}, if we want to create an @code{InternetNode} in a 
+script, we will 
+typically do something like the following example:
+
+@verbatim
+  Ptr<Node> p = Create<InternetNode> ();
+@end verbatim
+
+@cindex smart pointer
+To some, it may seem intuitively obvious that we're creating an
+@code{InternetNode} object and assigning responsibility for managing the 
+object to a smart pointer named @code{p}.  For the rest of us, there may be
+a lot in that line that is unfamiliar, so let's look at what this line means 
+in some detail.
+
+@subsection Templates 101
+@cindex template
+If you are familiar with C++ templates, you may skip this section as it is
+just a cursory introduction to function and class templates.
+
+Referring back to the example line of code, reproduced below for your 
+convenience, the angle brackets you see in the code indicate that we are
+using C++ @emph{templates}.  
+
+@verbatim
+  Ptr<Node> p = Create<InternetNode> ();
+@end verbatim
+
+The purpose of templates is to allow a programmer to write one version of code
+that is applicable over multiple types.  Some people consider templates to be
+an enhancement of the C preprocessor macro functionality.  At some level
+this comparison reveal some similarities, but C++ templates are really 
+quite different.
+
+@cindex template!declaration
+@cindex template!definition
+@cindex template!use
+In C++, just as with most language constructs, templates are @emph{declared}, 
+@emph{defined} and @emph{used}.  A declaration of a template might look
+something like,
+
+@verbatim
+  template <typename T> T Add (T first, T second);
+@end verbatim
+
+@cindex template!typename
+This line uses the keyword @code{template} followed by a declaration of a
+type name (in this case @code{T}) in angle brackets.  The angle brackets 
+should indicate to you that a template is being declared, defined or used.
+The type name @code{T} can be thought of as a string that will be substitited
+during the use phase of the template.  For example, the @code{T} may be
+replaced by the word @code{int}.  It is this substitution that leads people
+to compare templates with macros.
+
+Without going into too much more detail, this snippet declares that a piece
+of code exists that will be able to call a function @code{Add} that will
+add arbitrary types together.  The @code{T} will be eventually replaced by
+a C++ data type name.  For example,
+
+@verbatim
+  T Add (T first, T second);
+@end verbatim
+
+might eventually become
+
+@verbatim
+  int Add (int first, int second);
+@end verbatim
+
+If the template has been declared, we need to @emph{define} what that piece of
+code will actually do.  That might look something like,
+
+@verbatim
+  template <typename T> 
+  T Add (T first, T second)
+  {
+    return first + second;
+  }
+@end verbatim
+
+All we've done here is to provide an implementation of the template that 
+adds the two variables together and returns the result.  Note that this
+implementation works for any type that provides an @code{operator+}.
+
+The puzzle all comes together when you understand that @emph{using} a template
+causes the compiler to automatically instantiate code for a specific function 
+according to the given template parameters.  You might use the above template
+like,
+
+@verbatim
+  int x, y, z;
+  z = Add<int> (x, y);
+@end verbatim
+
+@cindex template!instantiate
+When the compiler sees @code{Add<int>} it understands that it needs to make
+sure that code is instantiated (created) to perform the @code{Add} using the
+specified type @code{<int>}.  To a first approximation, the compiler will 
+replace the typename @code{T} with the specified type @code{int} and 
+automagically generate code equivalent to,
+
+@verbatim
+  int Add (int first, int second)
+  {
+    return first + second;
+  }
+@end verbatim
+
+A user of the template definition could just as easily have provided a use
+that assigned the type float.  This would simply be done like,
+
+@verbatim
+  float x, y, z;
+  z = Add<float> (x, y);
+@end verbatim
+
+In this case, the compiler would automatically generate code that looked like,
+
+@verbatim
+  float Add (float first, float second)
+  {
+    return first + second;
+  }
+@end verbatim
+
+@cindex template!function
+This particular kind of template programming uses what are called
+@emph{function templates}.  They are called function templates since you 
+are @emph{templating} function declarations and definitions.
+
+@cindex template!class
+Templates can also be used in conjunction with classes, in which case you are
+said to be using, not too surprisingly, @emph{class templates}.  The syntax and
+use is similar.  To declare a class template you might use something like,
+
+@verbatim
+  template <typename T> 
+  class MyStack
+  {
+    void Push (T data);
+    T Pop (void);
+  };
+@end verbatim
+
+The methods can be defined separately in a method similar to function template
+definitions,
+
+@verbatim
+  template <typename T> void MyStack<T>::Push (T data)
+  {
+    ...
+  };
+@end verbatim
+
+You can then use the new templated class in the following way, 
+
+@verbatim
+  int x, y;
+
+  MyStack<int> stack;
+  stack.Push (x);
+  y = stack.Pop ();
+@end verbatim
+
+Similarly to the function template case, the compiler knows that it has to
+automatically generate code to fill out the class and method declarations
+and definitions using the appropriate type specified by @code{<int>}.
+
+@subsection Smart Pointers 101
+If you are familiar with C++ smart pointers, you may skip this section as it
+is just a cursory introduction to smart pointers and intrusive reference
+counting.
+
+@cindex smart pointer
+Referring back to the example line of code, partially reproduced below for 
+your convenience below, the left hand side is the declaration and
+initialization of a class template that implements a @emph{smart pointer}.
+
+@verbatim
+  Ptr<Node> p = ...
+@end verbatim
+
+To a first approximation, you can think of @code{Ptr<Node>} as the a new kind
+of declaration of a pointer to a @code{Node} object.  The difference is that
+a smart pointer is a user-defined data type (instantiated via a templated
+class) that @emph{simulates} a classical pointer but provides additional 
+features.  As an aside, you typically pronounce  @code{Ptr<Node>} as 
+``pooter node'' where pooter rhymes with footer.
+
+@cindex memory management
+One of the most important ``additional feature'' provided by smart pointers is
+automatic memory management.  Since you now understand class templates, you
+will understand how the template allows us to write the pointer code once, but
+allows us to point to many different kinds of objects.  Later in the tutorial
+you will see variations such as @code{Ptr<Ipv4>} and @code{Ptr<Channel>}, 
+which are smart pointers to an IP version 4 object and a channel object, 
+respectively.
+
+The use of built-in pointers in C and C++ is a major source of bugs.  Constant
+allocation of, passing of responsibility for, and deallocation of underlying
+data makes it very likely that errors will occur.  In one of these errors,
+the usual problem is that the responsibility for deallocating a memory block
+is misplaced.  This may result in a memory leak or a duplicate deallocation.
+Smart pointers try to prevent this kind of problem by working with the
+@emph{scope} and @emph{extent} rules of the language to make memory 
+deallocation automatic.
+
+The scope of a variable defines where in a program a given variable may be 
+referred to.  The extent of a variable defines when in the program's execution
+the variable has a valid value.  Consider a simple subroutine that contains a
+smart pointer.
+
+@verbatim
+  void SimpleSubroutine (void)
+  {
+    Ptr<Node> p;
+  }
+@end verbatim
+
+@cindex scope
+The variable named @code{p} has a scope limited to the subroutine itself.  The 
+variable is said to @emph{come into scope} as the subroutine is entered during
+execution.  At this time, the constructor of the underlying class is executed
+and a valid variable is available for use.  When the subroutine is done 
+executing, the variable is said to @emph{go out of scope}.  This causes the
+destructor of the underlying class to be executed and the variable no longer
+has a valid value.  This is not a problem since it is no longer valid to refer
+to the parameter.  Smart pointers take advantage of these defined actions at
+points where variables must be valid and become discardable to determine when
+underlying data can be freed.
+
+@cindex reference counting!intrusive
+The @command{ns-3} smart pointer mechanism uses a mechanism called intrusive 
+reference counting to determine when a memory block should be automatically 
+deallocated.  The term ``intrusive'' means that a reference count (a count of
+variables required to have valid data) is stored in the object being managed
+instead of in a proxy object.  This means that each piece of memory managed by
+a @command{ns-3} smart pointer includes a reference count.  When a smart 
+pointer to a reference counted object is created, this reference count is 
+incremented.  This indicates that a new variable requires a valid data object 
+be present.  When a smart pointer to a reference counted object is destroyed
+(for example, when going out of scope) the reference count of the managed 
+object is decremented.  When the reference count goes to zero it means that 
+all smart pointers to the underlying object have gone out of scope and the 
+object is no longer needed by any past ``users'' of the object.  This in turn
+means that the object can be safely deallocated, and this is done 
+automatically for you as the ``last'' smart pointer goes out of scope.
+
+Consider how this might work as you pass a smart pointer to an object down
+a protocol stack.  At each level of the stack, you pass the smart pointer
+by value.  This causes a copy of the smart pointer to be made, which 
+increments the reference count of the underlying object.  When the
+@emph{calling} method is done executing, the calling smart pointer goes out of 
+scope and  the reference count is decremented.  This leaves the single smart 
+pointer in the @emph{called} method with a reference to the underlying object.
+When the smart pointer in the called method goes out of scope, the destructor
+for the smart pointer is called.  The destructor checks the reference count
+of the underlying object and sees that it becomes zero.  This indicates that 
+the object can be deallocated, and the destructor does so.  This results in
+the lifetime management of the underlying object being automatically managed,
+a boon if you have experience with ``manual'' memory management and finding
+memory leaks.
+
+Now, we want to make this feature available as widely as possible to objects
+in the @command{ns-3} system.  The basic operations of the smart pointer class
+are the same across any intrusively reference counted object.  C++ provides a
+mechanism to achieve this kind of generic behavior -- the template.  Let's
+examine the declaration of the smart pointer in more detail.  First consider
+the way you might declare and use a built-in pointer.  For the sake of
+simplicity, just assume that a C++ object of the class @code{MyClass} exists.
+Further assume that @code{MyClass} provides one method called @code{method}.
+Using built-in pointers, you could do something like the following:
+
+@verbatim
+  MyClass *p = ...
+  p->method ();
+@end verbatim
+
+@cindex smart pointer
+One of the key design points of smart pointers is that they should simulate
+built-in pointers.  In C++ this is done by overloading @code{operator->}, 
+@code{operator=} and @code{operator*}.  To implement a smart pointer we need
+to provide a generic class that implements these operators.  This generic 
+class should allow operations that appear as if it were a built-in pointer
+to the reference counted object. Typically this is accomplished via a
+relatively simple C++ class template.  If you are interested in the details
+of how this may be accomplished, see Alexandrescu for a good treatment,
+
+@cindex template
+Taking the template as given, in order to declare a smart pointer you will
+need to create a smart pointer object and provide the template parameter
+needed to instantiate the required code.  This parameter will be the name
+of the reference counted class to which you want to point.  The smart
+pointer class overrides @code{operator=} which allows initialization of the
+smart pointer just as if it were a built-in pointer.  The end result is that
+you use smart pointers just as if they were built-in pointers:
+
+@verbatim
+  SmartPointer<MyClass> p = ...
+  p->method ();
+@end verbatim
+
+@subsection Object Creation
+@cindex Create
+On the right hand side of the line of code we're examining (reproduced below
+for convenience) is the creation of an @code{InternetNode} object.
+
+@verbatim
+  ... = Create<InternetNode> ();
+@end verbatim
+
+@cindex template!function
+This turns out to be an instance of use of a C++ @emph{function template}. The
+definition of the @code{Create<typename T>()} template calls the new operator
+to create an object of the type T.  It then creates a new smart pointer of
+the appropriate type (i.e., @code{Ptr<T>}).  This new smart pointer is
+assigned initial responsibility for the new object which has its reference
+count set to one.
+
+Since the underlying creation mechanism is via the @code{new} operator, and
+you can pass parameters to the constructor for an object, we provide several
+templates that you can use for passing parameters to the object constructors.
+If the constructor for the object requires a parameter, you simply pass that
+parameter to the @code{Create} function like this,
+
+@verbatim
+  int parm = 1;
+  ... = Create<MyClass> (parm);
+@end verbatim
+
+We provide Create templates with up to seven parameters, so you could 
+conceivably use the @code{Create} template in situations such as,
+
+@verbatim
+  int parm = 1;
+  ... = Create<MyClass> (p1, p2, p3, p4, p5, p6, p7);
+@end verbatim
+
+@subsection Type Safety
+Lets take one final look at the now infamous example line of code that we
+have been examining for some time (again reproduced below).
+
+@verbatim
+  Ptr<Node> p = Create<InternetNode> ();
+@end verbatim
+
+@cindex smart pointer
+@cindex Node
+@cindex Create
+You may have noticed that the smart pointer on the left hand side of the
+assignment is associated with the type @code{Node} and the @code{Create}
+template on the right hand side creates an @code{InternetNode} object and
+returns a @code{Ptr<InternetNode>} smart pointer.  For this assignment of a
+@code{Ptr<InternetNode>} to a @code{Ptr<Node>} to work, there must be some
+kind of type conversion going on.
+
+@cindex implicit conversion
+Many programmers use @code{implicit conversions} without even realizing it
+since they are sometimes so intuitive.  For example, in the following code,
+
+@verbatim
+  int i = 1;
+  double d = 2.;
+  if (n == d) ...
+@end verbatim
+
+@cindex standard conversion
+the integer (1) is implicitly converted to a double (1.) before the comparison
+takes place.  This conversion is performed using what is known as a C++ 
+@emph{standard conversion}.  There are a number of standard conversions defined
+by the C++ standard.  Among them are,
+
+@itemize @bullet
+@item Integral Promotions
+@item Integral Conversions
+@item Floating Conversions
+@item Pointer Conversions
+@item Reference Conversions
+@end itemize
+
+@cindex assignment operator
+@cindex Ptr
+For the case of interest here, we need to know what happens in the 
+assignment operator (@code{operator=}) of our smart pointer @code{Ptr<Node>}.
+This operator takes a reference to a @code{Ptr<Node>} and not a reference to
+a @code{Ptr<InternetNode>}.  The one situation where this works automatically
+in C++ is if the ``destination'' reference is to a visible, unambiguous base
+class of the ``source'' reference.  In this case, the underlying pointer is
+@emph{cast} from one type to the other automatically.
+
+To summarize: The magic happens in the assignment operator.  Class
+@code{InternetNode} inherits from class @code{Node}.  The reference to the
+@code{InternetNode} object in question is, in essence, a pointer to an
+@code{InternetNode} object.  The @code{InternetNode} class inherits from the
+@code{Node} base class in a way that makes @code{Node} visible and unambiguous.
+Therefore, there exists a standard conversion from an @code{InternetNode *} 
+to a @code{Node *} and by extension from an @code{InternetNode &} to a
+@code{Node &}.  This conversion is applied automatically (and invisibly) 
+during paramater passing in the assignment operator we are examining.
+
+@cindex base class
+This is a rather involved way of saying there's an invisible pointer cast
+to a base class happening in the assignment.  That means that
+
+@verbatim
+  Ptr<Node> p = Create<InternetNode> ();
+@end verbatim
+
+or,
+
+@verbatim
+  Ptr<Channel> p = Create<CsmaChannel> ();
+@end verbatim
+
+will work just fine.  Of course, if you try something @emph{bad} (TM), like:
+
+@verbatim
+  Ptr<Node> p = Create<CsmaChannel> ();
+@end verbatim
+
+the compiler will quite appropriately complain that there is no conversion
+between these completely unrelated objects (CsmaChannel and Node).
+
+@subsection Summary
+Going back to our infamous first line of @command{ns-3} code, we said that if 
+we want to create an InternetNode in a script, we will typically do something 
+like:
+
+@verbatim
+  Ptr<Node> p = Create<InternetNode> ();
+@end verbatim
+
+@cindex Create
+@cindex InternetNode
+@cindex smart pointer
+Now we know that this is really a simple statement.  We create an
+@code{InternetNode} object on the heap (indirecly using operator @code{new}
+and passing no parameters to its constructor) and assign responsibility for
+managing the new object's lifetime to a smart pointer.  This smart pointer is 
+a pointer to a @code{Node} object, so there was a hidden cast from 
+@code{InternetNode} to a @code{Node} done via a standard C++ conversion.  
+
+This may have been quite a hurdle to get past that first line of code, but
+we have covered quite a few of the important idioms that you'll encounter in
+this tutorial.
+
+@c ========================================================================
+@c A First ns-3 script
+@c ========================================================================
+
+@node A-First-ns-3-Script
+@chapter A First ns-3 script
+@cindex design pattern
+@cindex idiom
+Lets build a simple network using the @command{ns-3} design patterns, idioms,
+classes and helpers we have just looked at.  If you downloaded the system as
+was suggested above, you will have a release of @command{ns-3} in a directory 
+called @code{repos} under your home directory.  Change into that directory, 
+where you should see a directory structure something like the following.
+
+@verbatim
+  AUTHORS  RELEASE_NOTES  examples/  src/       waf*
+  LICENSE  VERSION        ns3/       tutorial/  waf.bat*
+  README   doc/           samples/   utils/     wscript
+@end verbatim
+
+@cindex hello-simulator.cc
+Change into the tutorial directory.  You should see a file named 
+@code{hello-simulator.cc} located there.  Copy this file into one named
+@code{simple.cc}.  If you open this new file in your favorite editor you will
+see some copyright information and the following C++ code:
+
+@verbatim
+  #include "ns3/log.h"
+
+  NS_LOG_COMPONENT_DEFINE ("HelloSimulator");
+
+  using namespace ns3;
+
+  int 
+  main (int argc, char *argv[])
+  {
+    LogComponentEnable ("HelloSimulator", LOG_LEVEL_INFO);
+
+    NS_LOG_INFO ("Hello Simulator");
+  }
+@end verbatim
+
+This is the @command{ns-3} version of the ubiquitous hello-world program.  It 
+uses the @command{ns-3} Log module to print ``Hello Simulator'' into the
+ standard error output stream.
+
+@cindex logging
+Log components are named objects that provide for controlling the verbosity of
+debugging output in the system.  We'll have a lot more to say about logging
+later on, but for now you can just consider the macro @code{NS_LOG_INFO} to be
+a kind of fancy printf to the standard error.
+
+@section A Simple Network
+@cindex InternetNode
+Let's create a simple network of @code{InternetNode} elements.  In order to
+actually create an @code{InternetNode}, you will have to include some header
+files.  Put the following code after the include statement in @code{simple.cc}.
+
+@verbatim
+  #include "ns3/ptr.h"
+  #include "ns3/internet-node.h"
+@end verbatim
+
+@cindex include files
+The @command{ns-3} build system places the core include files it needs into a 
+directory called @code{ns-3} and so whenever you need to include one of the
+core files you need to explicitly code this.  The file @code{ptr.h} defines
+the generic smart pointer that we use.  The file @code{internet-node.h}
+defines the class InternetNode which, as described above, represents an IP
+version 4-based computing element in the simulator.
+
+So let's create a few new @code{InternetNode}s by adding the following lines
+of code after the call to @code{NS_LOG_INFO} in the simple.cc file right 
+after the call to @code{NS_LOG_INFO}.
+
+@verbatim
+  Ptr<Node> n0 = Create<InternetNode> ();
+  Ptr<Node> n1 = Create<InternetNode> ();
+  Ptr<Node> n2 = Create<InternetNode> ();
+  Ptr<Node> n3 = Create<InternetNode> ();
+@end verbatim
+
+As we now understand, this will create four @code{InternetNode} objects on
+the heap and create four @code{Ptr<Node>} smart pointer objects on the stack
+to manage them.  You should remember that by using the smart pointers you are 
+freed from the responsibility to delete the objects you assign to them.
+
+@cindex Channel
+@cindex CsmaChannel
+The next step is to create a channel over which these nodes can communicate.
+Let's use the CsmaChannel and create a local area network that will allow us 
+to hook up nodes similarly to an Ethernet.
+
+As usual, we'll need to include the file that provides the appropriate class
+declarations:
+
+@verbatim
+  #include "ns3/csma-channel.h"
+@end verbatim
+
+Next, Add the following line of code (typically done after node creation) to 
+create a channel with a five megabit per second data rate and a two 
+millisecond speed-of-light delay between all nodes.  The idiom for creating
+the channel is similar to that of the node, but the actual @code{Create}
+function is hidden from us in the topology code.  Observe that we are 
+using a Csma topology helper function to free us from the details regarding
+how the Carrier Sense Multiple Access Channel is actually brought into
+existence and initialized.
+
+@verbatim
+  Ptr<CsmaChannel> lan = 
+    CsmaTopology::CreateCsmaChannel (DataRate (5000000), MilliSeconds (2));
+@end verbatim
+
+@cindex idiom!unnamed parameter
+You may be unfamiliar with the @emph{unnamed parameter} idiom used here.
+When added to a list of parameters, the code @code{DataRate (5000000)} 
+constructs a DataRate object on the stack using the appropriate  constructor.
+The resulting object has no name, and therefore cannot be referenced 
+elsewhere, but is passed to the callee method where it has a valid name and
+can be used.  This idiom is essentially a shorthand version of the following:
+
+@verbatim
+  DataRate rate (5000000);
+  Time latency (MilliSeconds (2));
+  Ptr<CsmaChannel> lan = CsmaTopology::CreateCsmaChannel (rate, latency);
+@end verbatim
+
+@cindex constructor
+@cindex constructor!Time
+We should pause for a moment and discuss the constructor to the @code{Time}
+data type.  There are a number of different constructors for these objects, and
+so there are a number of ways that this initialization could have been done.
+There is a constructor that takes a string argument, consisting of expressions
+using the units @code{s, ms, us, ns, ps} or @code{fs}, so this could have been
+written,
+
+@verbatim
+  Time latency ("2ms");
+@end verbatim
+
+There are also helper functions available that create time units (one of these
+was used in the example):
+
+@itemize @bullet
+@item @code{Seconds (double)}
+@item @code{MilliSeconds (uint64_t)}
+@item @code{MicroSeconds (uint64_t)}
+@item @code{NanoSeconds (uint64_t)}
+@item @code{PicoSeconds (uint64_t)}
+@item @code{FemtoSeconds (uint64_t)}
+@end itemize
+
+C++ will attempt to promote parameters appropriately, but you will typically
+see constructions that respect the type corrrectness of the constructor, as
+in @code{Seconds (1.)} and @code{MilliSeconds (2)}.  Notice that the code
+@code{Seconds (1)} will work just as well as @code{Seconds (1.)} since the 
+integer 1 will be automatically promoted to a double 1. in the former code.
+The converse will not work -- i.e., you cannot write code that says 
+@code{MilliSeconds (2.)} since a @emph{type demotion} would be required that 
+could lose information and the compiler will not do such things ``behind your
+back.''  Don't be thrown off by this kind of automatic conversion.
+
+@cindex MAC!address
+Okay, now we have code to create four nodes and a local area network.  The 
+next step is to wire the network together.  We do this by adding net devices 
+to the node.  When we add the net device, we also specify the network to which
+the net device is connected and provide a MAC address appropriate to the 
+device and network types.  Since we're creating an IP version 4 network using 
+a Csma channel, you may expect that we'll be using topology helpers 
+appropriate to those types -- the CsmaIpv4Topology helper.  As you may expect,
+we'll need to include some files to get the appropriate definitions:
+
+@verbatim
+  #include "ns3/mac48-address.h"
+  #include "ns3/csma-net-device.h"
+  #include "ns3/csma-topology.h"
+  #include "ns3/csma-ipv4-topology.h"
+@end verbatim
+
+Now, all that is left is to do the ``wiring'':
+
+@verbatim
+  uint32_t nd0 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n0, lan, 
+    Mac48Address("08:00:2e:00:00:00"));
+@end verbatim
+
+[Note the additional unnamed parameter idiom usage here.]
+
+This code calls the topology helper relating to Csma channels and IP version
+four nodes.  It asks to install a Csma net device ``into'' node zero
+(@code{n0}) connecting the device to the channel named (@code{lan}).  It also 
+assigns a MAC address to the net device.  You can add similar lines of code 
+connecting the other nodes to the lan (remembering to assign new MAC 
+addresses).
+
+@verbatim
+  uint32_t nd1 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n1, lan, 
+    Mac48Address("08:00:2e:00:00:01"));
+
+  uint32_t nd2 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n2, lan, 
+    Mac48Address("08:00:2e:00:00:02"));
+
+  uint32_t nd3 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n3, lan, 
+    Mac48Address("08:00:2e:00:00:03"));
+@end verbatim
+
+@cindex IP!address
+@cindex IP!network mask
+@cindex multihome
+Finally, we need to add IP addresses to our nodes.  The pointers to the 
+nodes are stored in n0, n1, n2 and n3.  We added net devices to each of
+the nodes and remembered the net device index numbers as nd0, nd1, nd2 and
+nd3.  You can add multiple net devices to each node resulting in a situation
+similar to a multi-homed host.  Each time you add a net device, you will get
+a new index.  Since the IP address for a multi-homed host is associated with
+a net device, we need to provide that index (which we have saved) to the
+topology helper.  We provide an IP version four address via the @command{ns-3} 
+class @code{Ipv4Address} which takes a dotted decimal string as a constructor 
+parameter.  We also provide a network mask using the @command{ns-3} class
+@code{Ipv4Mask} which also takes a dotted decimal string.  The code to 
+perform the IP address assignment, then, looks like the following:
+
+@verbatim
+  CsmaIpv4Topology::AddIpv4Address (n0, nd0, Ipv4Address ("10.1.1.1"), 
+    Ipv4Mask ("255.255.255.0"));
+
+  CsmaIpv4Topology::AddIpv4Address (n1, nd1, Ipv4Address ("10.1.1.2"), 
+    Ipv4Mask ("255.255.255.0"));
+
+  CsmaIpv4Topology::AddIpv4Address (n2, nd2, Ipv4Address ("10.1.1.3"), 
+    Ipv4Mask ("255.255.255.0"));
+
+  CsmaIpv4Topology::AddIpv4Address (n3, nd3, Ipv4Address ("10.1.1.4"), 
+    Ipv4Mask ("255.255.255.0"));
+@end verbatim
+
+We have now constructed a simulated network.  Your code should now look 
+something like the following,
+
+@verbatim
+  #include "ns3/log.h"
+  #include "ns3/ptr.h"
+  #include "ns3/internet-node.h"
+  #include "ns3/csma-channel.h"
+  #include "ns3/mac48-address.h"
+  #include "ns3/csma-net-device.h"
+  #include "ns3/csma-topology.h"
+  #include "ns3/csma-ipv4-topology.h"
+
+  NS_LOG_COMPONENT_DEFINE ("HelloSimulator");
+
+  using namespace ns3;
+
+  int 
+  main (int argc, char *argv[])
+  {
+    LogComponentEnable ("HelloSimulator", LOG_LEVEL_INFO);
+
+    NS_LOG_INFO ("Hello Simulator");
+
+    Ptr<Node> n0 = Create<InternetNode> ();
+    Ptr<Node> n1 = Create<InternetNode> ();
+    Ptr<Node> n2 = Create<InternetNode> ();
+    Ptr<Node> n3 = Create<InternetNode> ();
+
+    Ptr<CsmaChannel> lan = 
+      CsmaTopology::CreateCsmaChannel (DataRate (5000000), MilliSeconds (2));
+
+    uint32_t nd0 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n0, lan, 
+      Mac48Address("08:00:2e:00:00:00"));
+
+    uint32_t nd1 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n1, lan, 
+      Mac48Address("08:00:2e:00:00:01"));
+
+    uint32_t nd2 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n2, lan, 
+      Mac48Address("08:00:2e:00:00:02"));
+
+    uint32_t nd3 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n3, lan, 
+      Mac48Address("08:00:2e:00:00:03"));
+
+    CsmaIpv4Topology::AddIpv4Address (n0, nd0, Ipv4Address ("10.1.1.1"), 
+      Ipv4Mask ("255.255.255.0"));
+
+    CsmaIpv4Topology::AddIpv4Address (n1, nd1, Ipv4Address ("10.1.1.2"), 
+      Ipv4Mask ("255.255.255.0"));
+
+    CsmaIpv4Topology::AddIpv4Address (n2, nd2, Ipv4Address ("10.1.1.3"), 
+      Ipv4Mask ("255.255.255.0"));
+
+    CsmaIpv4Topology::AddIpv4Address (n3, nd3, Ipv4Address ("10.1.1.4"), 
+      Ipv4Mask ("255.255.255.0"));
+  }
+@end verbatim
+
+This script won't actually do anything yet.  The next trick will be to 
+convince our nodes to try and send some data over the network.
+
+@section Using Applications
+@cindex Create
+As mentioned above, we use @code{Application}s in @command{ns-3} to generate 
+the data used to drive simulations.  An @code{Application} is added to a 
+@command{ns-3} node conceptually just as if you would add an application to a 
+computer.  When an application is created (using the @code{Create} template) 
+we tell the application which @code{Node} it belongs to (and therefore on 
+which node it is running) by passing a smart pointer to that @code{Node} in 
+the constructor arguments.
+
+@subsection A UDP Echo Client Application
+To use an application, we first have to load the header file in which it is
+defined.  For the UDP echo client, this would mean adding the line,
+
+@verbatim
+#include "ns3/udp-echo-client.h"
+@end verbatim
+
+In order to create the UDP echo client application we will need to add the 
+following code:
+
+@verbatim
+  uint32_t packetSize = 1024;
+  uint16_t port = 7;
+  uint32_t maxPacketCount = 1;
+  Time interPacketInterval = Seconds (1.);
+
+  Ptr<UdpEchoClient> client = Create<UdpEchoClient> (n0, "10.1.1.2", port, 
+    maxPacketCount, interPacketInterval, packetSize);
+@end verbatim
+
+@cindex packet
+The first four lines have broken out the configuration parameters for the 
+application as named parameters for clarity.  We are telling the application
+to generate 1024 byte packets (@code{packetSize = 1024}); and to send these
+packets to port 7 (@code{port = 7;}).  The application is told to send at most
+one packet (@code{maxPacketCount = 1;}); and to delay for one second between
+packet sends (@code{interpacketInterval = Seconds(1.)}) which is not used since
+only one packet is sent.  We will defer addressing the type @code{Time} until
+we discuss the simulator engine.  For now just understand the semantics are
+to wait for one second.
+
+The code to actually create the @code{UdpEchoClient} application uses the
+same creation idiom as we have used previously.  Notice that we have a case
+where the @code{Create} template is used to pass parameters to the constructor
+of the underlying object.  
+
+@cindex implicit conversion sequence
+Notice that a string is passed as the second parameter.  The formal parameter
+to the constructor of the @code{UdpEchoClient} object is actually an
+@code{Ipv4Address}.  We get away with this since C++ allows what are called
+@emph{implicit conversion sequences} to occur between the argument in the
+function call and the corresponding parameter in the function declaration.
+Basically, C++ will try to figure out a way to convert parameters for you
+transparently.
+
+In this case the conversion sequence is based on the constructor for the
+Ipv4Address that takes a @code{char const *} as a parameter.  C++ notices 
+that @code{"10.1.1.2"} refers to a @code{char const *} and knows that it
+needs to get from there to an @code{Ipv4Address}.  The compiler notices that
+there is an @code{Ipv4Address} constructor that takes a @code{char const *} 
+and so it uses that constructor transparently to arrange for the conversion.  
+
+You therefore have several options for passing this value.  You can use an 
+explicit named variable as in the following:
+
+@verbatim
+  Ipv4Address addr ("10.1.1.2");
+  ...
+
+  Ptr<UdpEchoClient> client = Create<UdpEchoClient> (n0, addr, port, 
+    maxPacketCount, interPacketInterval, packetSize);
+@end verbatim
+
+@cindex idiom|unnamed parameter
+You can use the unnamed parameter idiom that we have previously seen:
+
+@verbatim
+  Ptr<UdpEchoClient> client = Create<UdpEchoClient> (n0, 
+    Ipv4Address ("10.1.1.2"), port, maxPacketCount, interPacketInterval, 
+    packetSize);
+@end verbatim
+
+Or you can rely on implicit conversion sequences as we just saw:
+
+@verbatim
+  Ptr<UdpEchoClient> client = Create<UdpEchoClient> (n0, "10.1.1.2", port, 
+    maxPacketCount, interPacketInterval, packetSize);
+@end verbatim
+
+Which approach to take is a matter of style, really, and you will probably
+see all three approaches taken in the @command{ns-3} code.  You should be 
+comfortable seeing and using all three methods.
+
+@subsection A UDP Echo Server Application
+As usual, to use the UDP echo server we need to add a line to define the
+application:
+
+@verbatim
+#include "ns3/udp-echo-server.h"
+@end verbatim
+
+In order to create the UDP echo server application we will need to add the 
+following code:
+
+@verbatim
+  Ptr<UdpEchoServer> server = Create<UdpEchoServer> (n1, port);
+@end verbatim
+
+We only need to tell the application which node to reside on and which port
+to listen on for UDP packets.  The code to actually create the
+@code{UdpEchoServer} application uses the now quite familiar @command{ns-3} object
+creation idiom.
+
+@subsection A UDP Echo Client-Server Simulation
+Now we're getting somewhere.  Your code should look something like the
+following (let's change the log component name and program banner from
+``Hello Simulator''to something more descriptive while we're at it).
+
+@verbatim
+  #include "ns3/log.h"
+  #include "ns3/ptr.h"
+  #include "ns3/internet-node.h"
+  #include "ns3/csma-channel.h"
+  #include "ns3/mac48-address.h"
+  #include "ns3/csma-net-device.h"
+  #include "ns3/csma-topology.h"
+  #include "ns3/csma-ipv4-topology.h"
+  #include "ns3/udp-echo-client.h"
+  #include "ns3/udp-echo-server.h"
+
+  NS_LOG_COMPONENT_DEFINE ("UdpEchoSimulation");
+
+  using namespace ns3;
+
+  int 
+  main (int argc, char *argv[])
+  {
+    LogComponentEnable ("UdpEchoSimulation", LOG_LEVEL_INFO);
+
+    NS_LOG_INFO ("UDP Echo Simulation");
+
+    Ptr<Node> n0 = Create<InternetNode> ();
+    Ptr<Node> n1 = Create<InternetNode> ();
+    Ptr<Node> n2 = Create<InternetNode> ();
+    Ptr<Node> n3 = Create<InternetNode> ();
+
+    Ptr<CsmaChannel> lan = 
+      CsmaTopology::CreateCsmaChannel (DataRate (5000000), MilliSeconds (2));
+
+    uint32_t nd0 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n0, lan, 
+      Mac48Address("08:00:2e:00:00:00"));
+
+    uint32_t nd1 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n1, lan, 
+      Mac48Address("08:00:2e:00:00:01"));
+
+    uint32_t nd2 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n2, lan, 
+      Mac48Address("08:00:2e:00:00:02"));
+
+    uint32_t nd3 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n3, lan, 
+      Mac48Address("08:00:2e:00:00:03"));
+
+    CsmaIpv4Topology::AddIpv4Address (n0, nd0, Ipv4Address ("10.1.1.1"), 
+      Ipv4Mask ("255.255.255.0"));
+
+    CsmaIpv4Topology::AddIpv4Address (n1, nd1, Ipv4Address ("10.1.1.2"), 
+      Ipv4Mask ("255.255.255.0"));
+
+    CsmaIpv4Topology::AddIpv4Address (n2, nd2, Ipv4Address ("10.1.1.3"), 
+      Ipv4Mask ("255.255.255.0"));
+
+    CsmaIpv4Topology::AddIpv4Address (n3, nd3, Ipv4Address ("10.1.1.4"), 
+      Ipv4Mask ("255.255.255.0"));
+
+    uint32_t packetSize = 1024;
+    uint16_t port = 7;
+    uint32_t maxPacketCount = 1;
+    Time interPacketInterval = Seconds (1.);
+
+    Ptr<UdpEchoClient> client = Create<UdpEchoClient> (n0, "10.1.1.2", port, 
+      maxPacketCount, interPacketInterval, packetSize);
+
+    Ptr<UdpEchoServer> server = Create<UdpEchoServer> (n1, port);
+
+  }
+@end verbatim
+
+@section Using the Simulation Engine
+@cindex model
+@cindex simulation executive
+You could say that the heart of the @command{ns-3} system is the 
+@emph{simulation engine} (sometimes called the simulation executive in other 
+systems).
+
+In a computer simulation, a computer @emph{model} of a real world @emph{system}
+is constructed.  This is typically done to minimize cost since you do not have
+to actually buy, install and maintain physical hardware.  In the case of
+@command{ns-3}, a model is a representation of a networking component that is
+designed to imitate some number of important behaviors or characteristics of 
+an actual component in a real network.  A system is a collection of models
+arranged for the purpose of analyzing some behavior.
+
+@section Models
+@cindex CsmaNetDevice
+@cindex CsmaChannel
+@cindex InternetNode
+@cindex NIC
+@cindex CSMA
+We have already encountered several @command{ns-3} models without specifically 
+calling them so.  The @code{InternetNode}, @code{CsmaNetDevice} and 
+@code{CsmaChannel} objects are models of an Internet computing node, a CSMA
+network interface card (NIC), and a network cable able to move data to and
+from other CSMA NICs.
+
+@cindex model
+@cindex CSMA/CD
+It is important to note that the @code{Csma} net devices and the @code{Csma}
+channel do not correspond to any real world hardware that you can actually go 
+out and buy.  These models implement an approximation, or subset, of the 
+behaviors that a real CSMA/CD network would have.  In this case, the
+@code{CsmaNetDevice} does not simulate collision detection (CD).  It does 
+implement carrier sense and performs collision @emph{avoidance} using global 
+spatial knowledge available in the channel.  This would be impossible in any
+channel residing in our universe.  
+
+@cindex Ethernet
+No model will fully implement @emph{all} of the behaviors of a piece of
+hardware.  It is important to understand what is being modeled by the 
+@command{ns-3} components you are using and what is not.  For example, the Csma
+components we use in this tutorial model a highly abstract multiple access
+network that is topologically equivalent to an Ethernet.  It is not necessarily
+true that results found in a simulation using the Csma models will apply to
+a real-world Ethernet network.  You must understand what behaviors are 
+simulated in each of the models before trusting that any results can be 
+associated with real-world systems.
+
+@section Time, Events and Callbacks
+@cindex time
+@cindex event
+In a @emph{discrete event simulator} time is not something that @emph{flows},
+nor is it something to be measured -- it is the driving force behind the
+progress of the simulation.  Time is progressed forward by the simulation 
+engine and anything that happens in the simulation is ultimately caused by
+an @emph{event}.  An event is some action in the system that is 
+@emph{scheduled} to happen at a certain time by the simulation engine.  Time 
+does not flow continuously but steps discretely (in possibly large jumps) 
+from one scheduled event to another.
+
+@cindex packet
+For example, to start the flow of a packet through the system, one would have
+to schedule an event with the simulation engine @emph{before} the simulation
+was started.  This is important since the simulation engine only jumps time
+forward if there is a next event to process.  The simulation stops if there
+are no more events, which is equivalent to a state where there is ``nothing 
+more to do.''  Before the simulation starts, one schedules driving events in 
+terms of absolute time.  For example, one could schedule an event to start 
+the flow of a first packet at, say, ten simulated seconds.  In this case, the 
+simulation would start its clock at zero seconds and look for the first event 
+in its @emph{event queue}.  It would immediately jump time forward by ten 
+seconds and @emph{fire} the scheduled event -- that is, make the event happen.
+
+@cindex functor
+@cindex function object
+@cindex callback
+@cindex Callback
+In @command{ns-3} an event is basically a pre-packaged function call called a 
+@emph{functor}.  Functors are also known as @emph{function objects}, which is
+a more descriptive term -- an object (in the object-oriented programming 
+sense) that can be called as if it was a function.  Typically one uses a
+functor to implement @emph{deferred execution} of a function or method.  The
+most commonly encoutered form of deferred execution is in a @emph{callback}
+from an I/O system.  In this case, the goal would be to start an I/O
+operation and return immediately, without having to wait for the operation 
+to complete.  One asks the I/O subsytem to notify you when an operation is
+complete by calling some function you provide.  This provided function is
+known as a callback function.  [Imagine calling someone on the telephone and
+asking them to do something for you.  You also ask them to @emph{call you back}
+when they are done.]  Events in the @command{ns-3} system work conceptually
+the same way, except that instead of an I/O completion driving the process,
+the arrival of some simulated time drives the process.  The @command{ns-3} 
+deferred exectution mechanism is via a class called @code{Callback}.
+
+@cindex Time
+@cindex Callback
+The internal details of the classes representing @code{Time} and 
+@code{Callback} abstractions will be introduced as required.  We won't see
+events directly for some time, but you should know that they are happening
+``under the sheets'' of the simulations you will be writing.
+
+@section Driving the Simulation
+@cindex Application
+As mentioned previously, time is the driving force behind the progress of
+a @command{ns-3} simulation.  Events are scheduled to happen at certain times
+by calling methods of the simulation engine, either directly or indirectly
+through, for example, an @code{Application}.
+
+In order to get the simulation engine set up and running in our code, we must
+first include the language definitions required to describe time- and
+simulator-specific classes:
+
+@verbatim
+  #include "ns3/simulator.h"
+  #include "ns3/nstime.h"
+@end verbatim
+
+@cindex Application
+As we have seen, we need to ``seed'' the simulation with at least one event.
+In the case of an @code{Application}, a method to do this is provided.  This
+method must be implemented by each specialization of the class and we must
+call this method in our script before the simulation starts.  We can also
+provide an event (indirectly) to stop the output of the application at a
+certain time.  This is done by adding the following lines to our script:
+
+@verbatim
+  server->Start(Seconds(1.));
+  client->Start(Seconds(2.));
+
+  server->Stop (Seconds(10.));
+  client->Stop (Seconds(10.));
+@end verbatim
+
+@cindex Application
+@cindex time
+@cindex Time
+@cindex socket
+@cindex event
+In the case of the UdpEchoServer, the call to @code{server->Start ()} gives
+the @code{Application} the chance to schedule an event that will perform the
+usual @emph{sockets} server sequence of socket creation, binding and
+recvfrom (see Donahoo's UDPEchoServer.c).
+
+In the case of the UdpEchoClient, the call to @code{client->Start ()} gives
+the @code{Application} the chance to schedule an event that will perform the
+usual @emph{sockets} client sequence of socket creation, sendto and recvfrom
+(see Donahoo's UDPEchoClient.c).  
+
+@cindex event
+Note that the start event for the server is scheduled to happen before the 
+start event of the client, just as you would start a server application before
+you would attempt to start a client application in the real world.
+
+@cindex socket!sendto
+The @command{ns-3} equivalent of the call to @code{sendo} in the client will 
+schedule (immediately) the transmission of a UDP packet over the just created
+socket.  This will cause the packet to percolate down the protocol stack and
+eventually into the channel.  The channel will schedule a reception event in
+the net device on the destination node.  This event will eventually percolate
+up into the server application.  The server application will create a reply
+packet and send it back down its stack and eventually back to the channel.
+The channel will schedule a reception event back in the client and this will
+cause the reply to be sent back up the protocol stack to the client 
+application.  
+
+The calls to @code{Stop ()} for both applications cause the sockets to be
+torn down and therefore the sending and receiving of packets will be stopped
+irrespective of other application settings (such as max packets and interval
+in the client).
+
+Finally, we need to run the simulation and when the simulation run is complete,
+clean up any resources allocated during the run.  This is done by the calling 
+the following static methods:
+
+@verbatim
+  Simulator::Run ();
+  Simulator::Destroy ();
+@end verbatim
+
+We now have the makings of a complete @command{ns-3} network simulation.  The 
+source code for the script should look like the following:
+
+@verbatim
+  #include "ns3/log.h"
+  #include "ns3/ptr.h"
+  #include "ns3/internet-node.h"
+  #include "ns3/csma-channel.h"
+  #include "ns3/mac48-address.h"
+  #include "ns3/csma-net-device.h"
+  #include "ns3/csma-topology.h"
+  #include "ns3/csma-topology.h"
+  #include "ns3/csma-ipv4-topology.h"
+  #include "ns3/udp-echo-client.h"
+  #include "ns3/udp-echo-server.h"
+  #include "ns3/simulator.h"
+  #include "ns3/nstime.h"
+
+  NS_LOG_COMPONENT_DEFINE ("UdpEchoSimulation");
+
+  using namespace ns3;
+
+  int 
+  main (int argc, char *argv[])
+  {
+    LogComponentEnable ("UdpEchoSimulation", LOG_LEVEL_INFO);
+
+    NS_LOG_INFO ("UDP Echo Simulation");
+
+    Ptr<Node> n0 = Create<InternetNode> ();
+    Ptr<Node> n1 = Create<InternetNode> ();
+    Ptr<Node> n2 = Create<InternetNode> ();
+    Ptr<Node> n3 = Create<InternetNode> ();
+
+    Ptr<CsmaChannel> lan = 
+      CsmaTopology::CreateCsmaChannel (DataRate (5000000), MilliSeconds (2));
+
+    uint32_t nd0 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n0, lan, 
+      Mac48Address("08:00:2e:00:00:00"));
+
+    uint32_t nd1 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n1, lan, 
+      Mac48Address("08:00:2e:00:00:01"));
+
+    uint32_t nd2 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n2, lan, 
+      Mac48Address("08:00:2e:00:00:02"));
+
+    uint32_t nd3 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n3, lan, 
+      Mac48Address("08:00:2e:00:00:03"));
+
+    CsmaIpv4Topology::AddIpv4Address (n0, nd0, Ipv4Address ("10.1.1.1"), 
+      Ipv4Mask ("255.255.255.0"));
+
+    CsmaIpv4Topology::AddIpv4Address (n1, nd1, Ipv4Address ("10.1.1.2"), 
+      Ipv4Mask ("255.255.255.0"));
+
+    CsmaIpv4Topology::AddIpv4Address (n2, nd2, Ipv4Address ("10.1.1.3"), 
+      Ipv4Mask ("255.255.255.0"));
+
+    CsmaIpv4Topology::AddIpv4Address (n3, nd3, Ipv4Address ("10.1.1.4"), 
+      Ipv4Mask ("255.255.255.0"));
+
+    uint32_t packetSize = 1024;
+    uint16_t port = 7;
+    uint32_t maxPacketCount = 1;
+    Time interPacketInterval = Seconds (1.);
+
+    Ptr<UdpEchoClient> client = Create<UdpEchoClient> (n0, "10.1.1.2", port, 
+      maxPacketCount, interPacketInterval, packetSize);
+
+    Ptr<UdpEchoServer> server = Create<UdpEchoServer> (n1, port);
+
+    server->Start(Seconds(1.));
+    client->Start(Seconds(2.));
+
+    server->Stop (Seconds(10.));
+    client->Stop (Seconds(10.));
+
+    Simulator::Run ();
+    Simulator::Destroy ();
+  }
+@end verbatim
+
+@cindex csma-echo.cc
+Just to make sure you don't get caught up in debugging typographical errors
+we have provided this source code for you (along with a copyright header) in
+the @code{tutorial} subdirectory of the @command{ns-3} distribution as 
+@code{csma-echo.cc}.  We used this opportunity to do some ``clean up''
+of some of our example cases by passing parameters using implicit conversion 
+sequences and removing some of the named parameters. [These were used for
+pedagogic purposes and were not actually necessary.]
+
+@section Building the Script
+@cindex Waf
+C++ is a compiled language, so you know it had to happen.  We have to build
+the script before we run it.  As mentioned before, we use the Waf build system
+which is Python-based.  We have to change gears slightly and switch ourselves
+to Python mode in order to proceed.
+
+In each subdirectory of the @command{ns-3} distribution in which there are
+source files, you will find two files:  one will be named @code{waf} and one
+will be named @code{wscript}.  The former, @code{waf}, is a link that allows
+one to start the build process from any subdirectory.  We can ignore that one.
+The file we need to deal with is @code{wscript}.
+
+@cindex wscript
+Open the file @code{ns-3-dev/tutorial/wscript} in your favorite editor
+[remember I'm assuming that you have the distribution saved in a
+repository under a directory called @code{repos} in you home directory.]
+
+@cindex Python
+You should see the following Python code (after an emacs mode line).
+
+@verbatim
+  def build(bld):
+    obj = bld.create_ns3_program('hello-simulator')
+    obj.source = 'hello-simulator.cc'
+@end verbatim
+
+These are the only instructions required to build a simulation (I told you
+it wasn't going to be too bad).  The line with the method
+@code{bld.create_ns3_program} tells the build system to create an object 
+file that is a program (executable) named @code{hello-simulator}.  The
+following line, with the method @code{obj.source} tells the build system that 
+the source file for the program is the file @code{hello-simulator.cc'} in the
+local directory.  The required libraries are linked for you for free.
+
+All that needed to be done in order to build the new simulation using the new
+source file was to copy the two lines describing the @code{hello-simulator} 
+program and change the names to @code{csma-echo}.  You can see these lines
+in the @code{wscript} file,
+
+@verbatim
+  def build(bld):
+    obj = bld.create_ns3_program('hello-simulator')
+    obj.source = 'hello-simulator.cc'
+
+    obj = bld.create_ns3_program('csma-echo')
+    obj.source = 'csma-echo.cc'
+
+    ...
+@end verbatim
+
+When you built the system above, you actually already built this new 
+simulation and a number of other examples.  Since you have already configured
+@code{Waf} and built the @code{csma-echo} script, you can run the simulation
+in the same way as you ran the @code{hello-simulator} script using the 
+@code{waf --run} command:
+
+@verbatim
+~/repos/ns-3-dev/tutorial > waf --run csma-echo
+Entering directory `~/repos/ns-3-dev/build'
+Compilation finished successfully
+UDP Echo Simulation
+~/repos/ns-3-dev/tutorial >
+@end verbatim
+
+Wow!  Wasn't that cool!  I'm sure you can barely contain yourself at this
+point.  Okay, well, maybe we should figure out how to get some useful
+information out of that simulation.  It did run ... I promise.
+
+@c ========================================================================
+@c Tracing at a Glance
+@c ========================================================================
+
+@node Tracing-at-a-Glance
+@chapter Tracing at a Glance
+
+At this stage we have constructed a real simulation script, but have no way
+of getting information out of the simulation.  Returning to first principles,
+a number of questions come immediately to mind:  What do we mean by getting
+information out of the simulation?  What is information?  How is this 
+information generated? What generates it? Where does it go?  How can we
+specify the quantity of information we get?  How can we specify the location
+of the sources?  What is a source anyway?
+
+@cindex toaster
+The @command{ns-3} tracing system addresses each of these questions.  At the 
+lowest levels, it is an extremely flexible module that comes with all of the 
+associated complexity that inevitably comes with flexibility.  To minimize
+the amount of work required to get started, we provide wrapper functions to 
+accomplish common tasks.  This makes the higher levels of the tracing system
+easy to use, but relatively inflexible.  This is a common trade-off.  Consider
+a toaster:  if you want to make toast, you can push a ``toast'' button; but if
+you want to control the color of your toast, you will need a knob to adjust. 
+If you want to independently control slice color, you will need a number of 
+knobs, etc.
+
+In this chapter, we will discuss the highest levels of the tracing system that
+expose the fewest ``knobs.''  
+
+@section ASCII Trace Wrapper
+@cindex ASCII
+The ASCII trace wrapper is a wrapper around the @command{ns-3} low-level 
+tracing system that lets you get access to underlying trace events easily.  
+The output of a trace of a simulation run is an ASCII file -- thus the name.  
+In the spririt of keeping things simple, you won't be able to control or 
+configure the output.  The details are all hidden from you, and are therefore 
+inaccessible at this level.  Be assured that as you learn more and more about
+the tracing system you will be able to control it to your heart's delight.
+
+@subsection Tracing Queue Operations
+@cindex queue
+Let's just jump right in.  As usual, we need to include the definitions
+related to using ASCII tracing (don't edit any files quite yet):
+
+@verbatim
+  #include "ns3/ascii-trace.h"
+@end verbatim
+
+We then need to add the code to the script to actually enable the ASCII tracing
+code.  The following code must be inserted before the call to 
+@code{Simulator::Run ();}:
+
+@verbatim
+  AsciiTrace asciitrace ("tutorial.tr");
+  asciitrace.TraceAllQueues ();
+@end verbatim
+
+@cindex AsciiTrace
+@cindex AsciiTrace!TraceAllQueues
+The first line declares an object of type @code{AsciiTrace} named
+@code{asciitrace} and passes a string parameter to its constructor.  This 
+parameter is a file name to which all of the trace information will be written.
+The last line, @code{asciitrace.TraceAllQueues ();} asks the trace object to 
+arrange that all queue operations (enqueue, dequeue, drop) on the queues 
+in all of the nodes of the system be traced.
+
+@cindex csma-echo-ascii-trace.cc
+Again, being the nice guys we are, we have provided you a file with these
+changes already made.  Make sure you understand what we've done before you 
+just move on.  The new file is called @code{csma-echo-ascii-trace.cc} and is
+located in the @code{tutorial} directory.  
+
+@cindex Waf
+You can just type the following to run the trace version of the echo program:
+
+@verbatim
+  ./waf --run csma-echo-ascii-trace
+@end verbatim
+
+@cindex tutorial.tr
+Just as you have seen previously, you will see some messages from @emph{Waf}
+and then (I feel joy) the ``Compilation finished successfully'' message.  The
+next message, @code{UDP Echo Simulation} is from the running program.  When 
+it ran, the program will have created a file named @code{tutorial.tr}.  
+Because of the way that Waf works, the file is not created in the local 
+directory, it is created at the top-level directory of the repository.  So, 
+change into the top level directory and take a look at the file 
+@code{tutorial.tr} in your favorite editor.
+
+@cindex trace event
+There's a lot of information there in a pretty dense form, but the first thing
+to notice is that there are a number of distinct lines in this file.  It may
+be difficult to see this clearly unless you widen your windows considerably.
+Each line in the file corresponds to a @emph{trace event}.  A trace event 
+happens whenever specific conditions happen in the simulation.  In this case
+we are tracing events on the @emph{device queue} present in every net device
+on every node in the simulation.  The device queue is a queue through which
+every packet destined for a channel must pass -- it is the device
+@emph{transmit} queue.  Note that each line in the trace file begins with a
+lone character (has a space after it).  This character will have the following
+meaning:
+
+@cindex enqueue
+@cindex dequeue
+@cindex drop
+@itemize @bullet
+@item @code{+}: An enqueue operation occurred on the device queue;
+@item @code{-}: A dequeue operation occurred on the device queue;
+@item @code{d}: A packet was dropped, typically because the queue was full.
+@end itemize
+
+Let's take a more detailed view of the first line.  I'll break it down into
+sections (indented for clarity) with a two digit reference number on the
+left side:
+
+@verbatim
+  00  + 
+  01  2 
+  02  nodeid=0 
+  03  device=0 
+  04  queue-enqueue 
+  05  pkt-uid=9 
+  06  ETHERNET 
+  07    length/type=0x806, 
+  08    source=08:00:2e:00:00:00, 
+  09    destination=ff:ff:ff:ff:ff:ff 
+  10      ARP(request 
+  11        source mac: 08:00:2e:00:00:00 
+  12        source ipv4: 10.1.1.1 
+  13        dest ipv4: 10.1.1.2) 
+  14  ETHERNET fcs=0
+@end verbatim
+
+@cindex trace event
+@cindex simulation time
+The first line of this expanded trace event (reference number 00) is the 
+queue operation.  We have a @code{+} character, so this corresponds to an
+@emph{enqueue} operation.  The second line (reference 01) is the simulation 
+time expressed in seconds.  You may recall that we asked the 
+@code{UdpEchoClient} to start sending packets at two seconds.  Here we see
+confirmation that this is, indeed, happening.
+
+@cindex node number
+@cindex net device number
+@cindex smart pointer
+The next lines of the example listing (references 02 and 03) tell us that
+this trace event originated in a given node and net device.  Each time a node
+is created it is given an identifying number that monotonically increases from
+zero.  Therefore, @code{nodeid=0} means that the node in which the given trace
+event originated is the first node we created.  In the case of our script, 
+this first node is is the node pointed to by the smart pointer @code{n0}.  Not
+too surpsisingly, this is also the node to which we attached the
+@code{UdpEchoClient}.  The device number is local to each node, and so the
+device given by @code{device=0} is the first net device that we added to the
+node in question.  In our simulation, this corresponds to the 
+@code{CsmaNetDevice} we added to node zero (@code{n0}).
+
+@cindex uid
+@cindex unique ID
+@cindex packet
+The next line (reference 04) is a more readable form of the operation code
+seen in the first line -- i.e., the character @code{+} means 
+@code{queue-enqueue}.  Reference number 05 indicates that the @emph{unique id}
+of the packet being enqueued is @code{9}.  The fact that the first packet we
+see has a unique ID of 9 should indicates to you that other things have 
+happened in the protocol stack before we got to this point.  This will become
+clear momentarily.
+
+@cindex Ethernet
+@cindex MAC address
+Reference items 06 and 14 indicate that this is an Ethernet packet with 
+a zero (not computed) checksum (note the indentation to make parsing this 
+trace event a little easier).  Reference 08 and 09 are the source and
+destination addresses of this packet.  The packet is from the MAC address we
+assigned to the node zero net device in the script, and is destined for the
+broadcast address -- this is a broadcast packet.
+
+@cindex Address Resolution Protocol
+@cindex ARP
+@cindex ARP|request
+Reference items 10 through 13 make clear what is happening.  This is an ARP
+(Address Resolution Protocol) request for the MAC address of the node on
+which the @code{UdpEchoServer} resides.  The protocol stack can't send a UDP
+packet to be echoed until it knows (resolves) the MAC address; and this trace
+event corresponds to an ARP request being queued for transmission to the local
+network.  The next line in the trace file (partially expanded),
+
+@verbatim
+  00  - 
+  01  2 
+  02  nodeid=0 
+  03  device=0 
+  04  queue-dequeue 
+  05  pkt-uid=9 
+  ...
+@end verbatim
+
+shows the (same) ARP request packet being dequeued from the device queue by
+the net device and (implicitly) being sent down the channel to the broadcast
+MAC address.  We are not tracing net device reception events so we don't 
+actually see all of the net devices receiving the broadcast packet.  We do,
+however see the following in the third line of the trace file:
+
+@verbatim
+  00  + 
+  01  2.00207
+  02  nodeid=1 
+  03  device=0 
+  04  queue-enqueue 
+  05  pkt-uid=10 
+  06  ETHERNET 
+  07    length/type=0x806, 
+  08    source=08:00:2e:00:00:01, 
+  09    destination=08:00:2e:00:00:00,
+  10      ARP(reply 
+  11        source mac: 08:00:2e:00:00:01 
+  12        source ipv4: 10.1.1.2 
+  13        dest mac: 08:00:2e:00:00:00 
+  14        dest ipv4: 10.1.1.1) 
+  15  ETHERNET fcs=0
+@end verbatim
+
+@cindex simulation time
+@cindex ARP|response
+Notice that this is a queue-enqueue operation (references 00 and 04) happening
+on node one (reference 02) at simulation time 2.00207 seconds (reference 01).
+Looking at the packet payload (references 10-14) we see that this is an ARP
+reply to the request sent by node one.  Note that the simulation time
+(reference 01) is now 2.00207 seconds.  This is direct result of the data rate
+(5 mb/s) and latency (2 ms) parameters that we passed to the 
+@code{CsmaChannel} when we created it.  Clearly the ARP request packet was 
+sent over the channel and received approximately 2 ms later by node one.  A
+corresponding ARP response packet was created and enqueued on node one's net
+device.  It is this enqueue trace event that has being logged.  
+
+@cindex queue
+@cindex queue|transmit
+@cindex echo
+Given the current state of affairs, the next thing you may expect to see is 
+this ARP request being received by node zero, but remember we are only looking
+at trace events on the device @emph{transmit} queue.  The reception of the ARP
+response by node zero will not directly trigger any trace event in this case, 
+but it will enable the protocol stack to continue what it was originally doing
+(trying to send an echo packet).  Thus, the next line we see in the trace file
+(@code{tutorial.tr}) is the first UDP echo packet being sent to the net device.
+
+@verbatim
+  00 + 
+  01 2.00415 
+  02 nodeid=0 
+  03 device=0 
+  04 queue-enqueue 
+  05 pkt-uid=7 
+  06 ETHERNET 
+  07   length/type=0x800, 
+  08   source=08:00:2e:00:00:00, 
+  09   destination=08:00:2e:00:00:01 
+  10   IPV4(
+  11     tos 0x0 
+  12     ttl 64 
+  13     id 0 
+  14     offset 0 
+  15     flags [none] 
+  16     length: 1052) 10.1.1.1 > 10.1.1.2 
+  17     UDP(length: 1032) 
+  18       49153 > 7 
+  19       DATA (length 1024) 
+  20 ETHERNET fcs=0
+@end verbatim
+
+@cindex simulation time
+@cindex echo
+@cindex ARP
+@cindex ARP|request
+@cindex ARP|response
+@cindex IP
+@cindex Ipv4
+I won't go into too much detail about this packet, but I will point out a
+few key items in the trace.  First, the packet was enqueued at simulation time
+of 2.00415 seconds.  This time reflects the fact that the echo client 
+application started at 2. seconds and there were two ARP packets transmitted
+across the network (two milliseconds + data transmission time each way).  The
+packet unique identifier (reference 05) is 7.  Notice that this is a lower
+number than the ARP request packet, which had a unique ID of 9.  This tells
+us that the UDP packet was actually created before the ARP request packet --
+which makes perfect sense since it was the attempt to send packet 7 that 
+triggered sending the ARP request packet 9.  Note that this an Ethernet
+packet (reference 06) like all other packets in this simulation, however this 
+particular packet carries an IPV4 payload and therefore has an IP version 4
+header (indicated by references 10-16).  This Ipv4 in turn contains a UDP
+header (references 17, 18) and finally 1024 bytes of data (reference 20).
+Clearly, this is the UDP echo packet emitted by the
+@code{UdpEchoClient Application}.
+
+The next trace event is an ARP request from node one.  We can infer that node
+one has received the UDP echo packet and the @code{UdpEchoServer Application}
+on that node has turned the packet around.  Just as node zero needed to ARP
+for the MAC address of node one, now node one must ARP for the MAC address of
+node zero.  We see the ARP request enqueued on the transmit queue of node one;
+then we see the ARP request dequeued from the tranmit queue of node one (and
+implicitly transmitted to node zero).  Then we see an ARP response enqueued
+on the transmit queue of node zero; and finally the ARP response dequeued (and
+implicitly transmitted back to node one).
+
+This exchange is summarized in the following trace event excerpts,
+
+@verbatim
+  + 2.00786 nodeid=1 ... ARP(request ...
+  - 2.00786 nodeid=1 ... ARP(request ...
+  + 2.00994 nodeid=0 ... ARP(reply ...
+  - 2.00994 nodeid=0 ... ARP(reply ...
+@end verbatim
+
+The final two trace events in the @code{tutorial.tr} file correspond to the 
+echoed packet being enqueued for transmission on the net device for node one,
+and that packet being dequeued (and implicitly transmitted back to node zero).
+
+@subsection Tracing Device Receive Operations
+There is one final ``knob'' we can turn on the ASCII trace wrapper.  We can
+enable net device receive operations.  In our analysis of the existing trace
+file we noted several times that we inferred that a packet was received by
+a given node.  We will now enable the event to actually trace that operation.
+
+All we have to do is add one more line to the file @code{csma-echo.cc} to
+enable tracing of net device receive operations.  The code is already in the
+file, but disabled.
+
+@cindex AsciiTrace!TraceAllNetDeviceRx
+@verbatim
+#if 0
+  asciitrace.TraceAllNetDeviceRx ();
+#endif
+  asciitrace.TraceAllNetDeviceRx ();
+@end verbatim
+
+Change the @code{#if 0} to @code{#if 1} using your favorite editor and compile
+and run the file using waf as we have done previously:
+
+@verbatim
+  ./waf --run csma-echo-ascii-trace
+@end verbatim
+
+@cindex ARP!request
+Now if you look at the trace file (@code{tutorial.tr}) you will see some new
+entries.  These entries all begin with the character @code{r} indicating a
+@emph{receive} trace event.  Recall that the first packet sent on the network
+was a broadcast ARP request.  We should then see all four nodes receive a
+copy of this request.  This is the case, as the first four receive trace
+events are,
+
+@verbatim
+  r 2.00207 nodeid=0 device=0 dev-rx pkt-uid=9 ARP(request ...
+  r 2.00207 nodeid=1 device=0 dev-rx pkt-uid=9 ARP(request ...
+  r 2.00207 nodeid=2 device=0 dev-rx pkt-uid=9 ARP(request ...
+  r 2.00207 nodeid=3 device=0 dev-rx pkt-uid=9 ARP(request ...
+@end verbatim
+
+@cindex unique ID
+You can see that a copy of the broadcast packet with unique ID 9 was received
+by the net devices on nodes 0, 1, 2 and 3.  We leave it up to you to parse the
+rest of the trace file and understand the remaining reception events.
+
+@section PCAP Trace Wrapper
+@cindex pcap
+@cindex Wireshark
+The @command{ns-3} @emph{pcap trace wrapper} is used to create trace files in
+@code{.pcap} format.  The acronym pcap (usually written in lower case) stands
+for @emph{p}acket @emph{cap}ture, and is actually an API that includes the 
+definition of a @code{.pcap} file format.  The most popular program that can
+read and display this format is Wireshark (formerly called Ethereal).
+
+If you are unfamilar with Wireshark, there is a web site available from which
+you can download programs and documentation:  @uref{http://www.wireshark.org/}.
+
+@cindex csma-echo-ascii-trace.cc
+@cindex csma-echo-pcap-trace.cc
+The code used to enable pcap tracing is similar to that for ASCII tracing.  
+We have provided another file, @code{csma-echo-pcap-trace.cc} that uses the
+pcap trace wrapper.  We have added the code to include the pcap trace wrapper
+defintions:
+
+@verbatim
+  #include "ns3/pcap-trace.h"
+@end verbatim
+
+And then added the following code below the AsciiTrace methods:
+
+@cindex PcapTrace
+@cindex PcapTrace!TraceAllIp
+@verbatim
+  PcapTrace pcaptrace ("tutorial.pcap");
+  pcaptrace.TraceAllIp ();
+@end verbatim
+
+The first line of the code immediately above declares an object of type
+@code{PcapTrace} named @code{pcaptrace} and passes a string parameter to its
+constructor.  This object is used to hide the details of the actual tracing
+subsystem.  The parameter is a base file name from which the actual trace file
+names will be built.  The second line of code tells the @code{PcamTrace}
+object to trace all IP activity in all of the nodes present in the simulation.
+
+@cindex interface index
+Trace files are not created until trace activity is detected.  Each file name 
+is composed of the base file name, followed by a @code{'-'}, a node id followed
+by a @code{'-}', and an IP interface index.  You will soon see a file named
+@code{tutorial.pcap-0-1}, for example.  This will be the trace file generated
+as events are detected on node zero, interface index one.  N.B. Interface 
+indices are different that net device indices -- interface index zero 
+corresponds to the loopback interface and interface index one corresponds to
+the first net device you added to a node.
+
+You may run the new program just like all of the others so far:
+
+@cindex Waf
+@verbatim
+  ./waf --run csma-echo-pcap-trace
+@end verbatim
+
+If you look at the top level directory of your distribution, you should now
+see three log files:  @code{tutorial.tr} is the ASCII trace file we have 
+previously examined.  @code{tutorial.pcap-0-1} and @code{tutorial.pcap-1-1}
+are the new pcap files we just generated.  There will not be files 
+corresponding to nodes two and three since we have not sent any IP packets to
+those nodes.
+
+@cindex Wireshark
+If you have Wireshark available, you can open each of the trace files and
+display the contents as if you had captured the packets using a
+@emph{packet sniffer}.  Note that only IP packets are traced using this
+wrapper, so you will not see the ARP exchanges that were logged when using
+the ASCII trace wrapper.  You are encouraged to take a look at the contents
+of these pcap files using your favorite pcap software (or Wireshark).
+
+@c ========================================================================
+@c Other Network Topologies
+@c ========================================================================
+
+@node Other-network-topologies
+@chapter Other Network Topologies
+@cindex topology
+@cindex Channel
+@cindex NetDevice
+@cindex topology!bus
+@cindex topology!point-to-point
+@cindex PointToPointChannel
+@cindex PointToPointNetDevice
+
+@emph{Network topology} is the study of the arrangement of of the elements
+(in @command{ns-3} represented by the classes @code{Channel} and @code{Node})
+of a network.  Two fundamental types of physical topologies are the 
+@emph{point-to-point} and @emph{bus} topologies.  We have already been exposed
+to the @command{ns-3} channel specialization named @code{CsmaChannel}.  This is
+a simulation of a bus network.  We also provide a simulation of a 
+point-to-point channel with associated net devices.  As described previously,
+the associated C++ classes specialize the @command{ns-3} base classes
+@code{NetDevice} and @code{Channel} and are called @code{PointToPointNetDevice}
+and @code{PointToPointChannel} respectively.
+
+We will use combinations of these bus and point-to-point topology elements
+to show how to create several commonly seen network topologies.
+
+@section A Point-to-Point Network
+We're going to take what might be seen as a step backward and look at a simple
+point-to-point network.  We will be building the simplest network you can 
+imagine.  A serial link (point to point) between two computers.  When you
+see this point-to-point network, you can think of an RS-422 (or RS-232 for 
+you old-timers) cable.  This topology is shown below.
+
+@sp 1
+@center @image{pp,,,,png}
+
+We have provided a file for you in the @code{tutorial}
+directory called @code{point-to-point.cc}.  You should now be familiar enough
+with the system to pick out fairly easily what has been changed.  Let's focus
+on the following lines:
+
+@verbatim
+  Ptr<Node> n0 = Create<InternetNode> ();
+  Ptr<Node> n1 = Create<InternetNode> ();
+
+  Ptr<PointToPointChannel> link = PointToPointTopology::AddPointToPointLink (
+    n0, n1, DataRate (38400), MilliSeconds (20));
+
+  PointToPointTopology::AddIpv4Addresses (link, n0, "10.1.1.1",
+    n1, "10.1.1.2");
+@end verbatim
+
+You can see that we created two @code{InternetNode} objects in the usual way.
+Then, instead of creating a @code{CsmaChannel} we create a 
+@code{PointToPointChannel}.  This point-to-point channel, which we call
+@code{link}, connects node zero (@code{n0}) and node one (@code{n1}) over a
+simulated link that runs at 38400 bits per second and has a 20 millisecond
+simulated speed-of-light delay.  This call also creates appropriate net devices
+and attaches them to nodes zero and one.
+
+We then add IP addresses to the net devices we just created using the topology
+helper @code{AddIpv4Addresses}.  Node zero gets the IP address 10.1.1.1 and
+node one gets the IP address 10.1.1.2 assigned.  
+
+The alert tutorial user may wonder what the network number or prefix is of
+those IP addresses.  The point-to-point topology assumes that you want a
+@code{/30} subnet and assigns an appropriate net mask for you.  It then then
+@emph{asserts} that the network numbers of the two net devices match.  So there
+is an implicit network mask created down in the topology code that looks like,
+
+@verbatim
+  Ipv4Mask netmask("255.255.255.252");
+@end verbatim
+
+The rest of the code you should recognize and understand.  We are just going
+to echo one packet across the point-to-point link.  You should be now be able
+to build and run this example and to locate and interpret the ASCII trace 
+file.  This is left as an exercise for you.
+
+The file @code{point-to-point.cc} is reproduced here for your 
+convenience:
+
+@verbatim
+/* -*- 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/ptr.h"
+#include "ns3/internet-node.h"
+#include "ns3/point-to-point-channel.h"
+#include "ns3/mac48-address.h"
+#include "ns3/point-to-point-net-device.h"
+#include "ns3/point-to-point-topology.h"
+#include "ns3/udp-echo-client.h"
+#include "ns3/udp-echo-server.h"
+#include "ns3/simulator.h"
+#include "ns3/nstime.h"
+#include "ns3/ascii-trace.h"
+#include "ns3/pcap-trace.h"
+#include "ns3/global-route-manager.h"
+
+NS_LOG_COMPONENT_DEFINE ("PointToPointSimulation");
+
+using namespace ns3;
+
+// Network topology
+//
+//                       point to point
+//                      +--------------+
+//                      |              |
+//                     n0             n1
+//
+int 
+main (int argc, char *argv[])
+{
+  LogComponentEnable ("PointToPointSimulation", LOG_LEVEL_INFO);
+
+  NS_LOG_INFO ("Point to Point Topology Simulation");
+
+  Ptr<Node> n0 = Create<InternetNode> ();
+  Ptr<Node> n1 = Create<InternetNode> ();
+
+  Ptr<PointToPointChannel> link = PointToPointTopology::AddPointToPointLink (
+    n0, n1, DataRate (38400), MilliSeconds (20));
+
+  PointToPointTopology::AddIpv4Addresses (link, n0, "10.1.1.1", 
+    n1, "10.1.1.2");
+
+  uint16_t port = 7;
+
+  Ptr<UdpEchoClient> client = Create<UdpEchoClient> (n0, "10.1.1.2", port, 
+    1, Seconds(1.), 1024);
+
+  Ptr<UdpEchoServer> server = Create<UdpEchoServer> (n1, port);
+
+  server->Start(Seconds(1.));
+  client->Start(Seconds(2.));
+
+  server->Stop (Seconds(10.));
+  client->Stop (Seconds(10.));
+
+  AsciiTrace asciitrace ("tutorial.tr");
+  asciitrace.TraceAllQueues ();
+  asciitrace.TraceAllNetDeviceRx ();
+
+  Simulator::Run ();
+  Simulator::Destroy ();
+}
+@end verbatim
+
+@section A Star Network
+A point-to-point network is considered a special case of a star network.  As
+you might expect, the process of constructing a star network is an extension
+of the very simple process used for a point-to-point link.  We have provided
+a file for you in the @code{tutorial} directory called @code{star.cc}
+that implements a simple star network as seen below.
+
+@sp 1
+@center @image{star,,,,png}
+
+In order to create a star network, we need to be able to instantiate some
+number (greater than one) of net devices on a node.  In the name of simplicity
+of use, the @code{PointToPointTopology} topology helper does not allow one to
+do this.  We provided a separate topology helper class, the 
+@code{PointToPointIpv4Topology} helper class that provides the slightly finer
+granularity we need to accomplish a star network.  In order to use this new
+helper we have to load the definitions by including the appropriate file.
+
+@verbatim
+  #include "ns3/point-to-point-ipv4-topology.h"
+@end verbatim
+
+The star that we're going to create has a node in the center (@code{n0}) with
+six nodes surrounding (@code{n1} - @code{n6}).  You should be able to easily
+find and understand the code that creates these nodes.
+
+@verbatim
+  Ptr<Node> n0 = Create<InternetNode> ();
+  Ptr<Node> n1 = Create<InternetNode> ();
+  Ptr<Node> n2 = Create<InternetNode> ();
+  Ptr<Node> n3 = Create<InternetNode> ();
+  Ptr<Node> n4 = Create<InternetNode> ();
+  Ptr<Node> n5 = Create<InternetNode> ();
+  Ptr<Node> n6 = Create<InternetNode> ();
+@end verbatim
+
+Next, we get into the differences between the @code{PointToPointTopology}
+helper and the @code{PointToPointIpv4Topology} helper.  The
+@code{PointToPointIpv4Topology} helper looks and feels a little like the 
+@code{CsmaIpv4Topology} helper.  Just like you created a CSMA channel 
+previously, you need to create a point-to-point channel.  The following
+code creates a @code{PointToPointChannel} and calls it @code{link01}.  You can
+interpret this name as being the channel (or @emph{link}) from node zero to 
+node one.  
+
+@verbatim
+  Ptr<PointToPointChannel> link01 =
+    PointToPointIpv4Topology::CreateChannel (DataRate (38400),
+    MilliSeconds (20));
+@end verbatim
+
+You need to provide a data rate for the channel which we set at 38400 bits 
+per second.  You must also provide a speed-of-light delay which we set at
+20 milliseconds.
+
+Just as you added a net device to the nodes in the CSMA tutorial section, you
+do the same here but with a point-to-point net device.  The following code
+illustrates how we do that:
+
+@verbatim
+  uint32_t nd01 = PointToPointIpv4Topology::AddNetDevice (n0,
+    link01);
+@end verbatim
+
+We call the @code{PointToPointIpv4Topology} helper and ask it to add a net
+device to node zero (@code{n0}) and connect it to the appropriate 
+point-to-point link (@code{link01}) which you will recall is the serial link
+from node zero to node one.
+
+If you look at the following code, you will see the same calls are repeated
+to create the remaining five point-to-point channels and connect them
+to net devices on node zero.
+
+The next new code is found after the ``spokes'' of the star have been created.
+It looks like the following:
+
+@verbatim
+  uint32_t nd1 = PointToPointIpv4Topology::AddNetDevice (n1, link01);
+  uint32_t nd2 = PointToPointIpv4Topology::AddNetDevice (n2, link02);
+  uint32_t nd3 = PointToPointIpv4Topology::AddNetDevice (n3, link03);
+  uint32_t nd4 = PointToPointIpv4Topology::AddNetDevice (n4, link04);
+  uint32_t nd5 = PointToPointIpv4Topology::AddNetDevice (n5, link05);
+  uint32_t nd6 = PointToPointIpv4Topology::AddNetDevice (n6, link06);
+@end verbatim
+
+Here we are creating the net devices on the nodes surrounding the center node.
+In the first call, we are adding a net device on node one (@code{n1}) and
+connecting that net device to the channel named @code{link01}.  Remember that
+we created the channel @code{link01} as the channel connecting node zero and
+node one.  We previously created a net device on node zero and attached that
+device to @code{link01}.  Here we are connecting the other side of that link
+to node one.  The return value from this call is the net device index of the
+created net device.
+
+The next section of code adds addresses to the net devices we just created.
+The first call adds the IP address 10.1.1.1 to the net device going from 
+node zero to node one.  Recall that we first created a node named @code{n0}
+and a channel called @code{link01}.  We added a net device to @code{n0} and
+remembered the net device index as the @code{uint32_t nd01}.  This meant
+the net device @emph{nd} on node @emph{0} that we connected to node @emph{1}. 
+We call @code{AddAddress} to add an IP address (10.1.1.1) to the net device
+on node zero identified by the net device index @code{nd01}.  We provide a
+net mask suitable for a point to point network.  This is typically a /30 
+address but we don't force that in this API.
+
+After setting up the address on node zero, we do the same for the node on
+the other end of the ``spoke'' -- in this case node one, with its single
+net device.  Note that the network number is the same on both sides of this
+network.
+
+@verbatim
+  PointToPointIpv4Topology::AddAddress (n0, nd01, "10.1.1.1",
+    ``255.255.255.252'');
+
+  PointToPointIpv4Topology::AddAddress (n1, nd1, "10.1.1.2",
+    ``255.255.255.252'');
+@end verbatim
+
+The following code repeats this pattern assining similar IP addresses to the
+remaining net devices.  Note that there are no @code{Mac48Address} address
+assignments -- they are not required.
+
+The rest of the code you should recognize and understand.  We are just going
+to echo one packet across the point-to-point link.  You should be now be able
+to build and run this example and to locate and interpret the ASCII trace 
+file.  This is left as an exercise for you.
+
+The file @code{star.cc} is reproduced here for your convenience:
+
+@verbatim
+/* -*- 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/ptr.h"
+#include "ns3/internet-node.h"
+#include "ns3/point-to-point-channel.h"
+#include "ns3/mac48-address.h"
+#include "ns3/point-to-point-net-device.h"
+#include "ns3/point-to-point-ipv4-topology.h"
+#include "ns3/udp-echo-client.h"
+#include "ns3/udp-echo-server.h"
+#include "ns3/simulator.h"
+#include "ns3/nstime.h"
+#include "ns3/ascii-trace.h"
+#include "ns3/pcap-trace.h"
+#include "ns3/global-route-manager.h"
+
+NS_LOG_COMPONENT_DEFINE ("StarSimulation");
+
+using namespace ns3;
+
+// Network topology
+//
+//                  n3    n2
+//                   |   /
+//                    | /
+//              n4 --- n0 --- n1
+//                    /  |
+//                   /    |
+//                  n5    n6
+
+int 
+main (int argc, char *argv[])
+{
+  LogComponentEnable ("StarSimulation", LOG_LEVEL_INFO);
+
+  NS_LOG_INFO ("Star Topology Simulation");
+
+  Ptr<Node> n0 = Create<InternetNode> ();
+  Ptr<Node> n1 = Create<InternetNode> ();
+  Ptr<Node> n2 = Create<InternetNode> ();
+  Ptr<Node> n3 = Create<InternetNode> ();
+  Ptr<Node> n4 = Create<InternetNode> ();
+  Ptr<Node> n5 = Create<InternetNode> ();
+  Ptr<Node> n6 = Create<InternetNode> ();
+
+  Ptr<PointToPointChannel> link01 = 
+    PointToPointIpv4Topology::CreateChannel (DataRate (38400), 
+    MilliSeconds (20));
+
+  uint32_t nd01 = PointToPointIpv4Topology::AddNetDevice (n0,
+    link01);
+
+  Ptr<PointToPointChannel> link02 = 
+    PointToPointIpv4Topology::CreateChannel (DataRate (38400), 
+    MilliSeconds (20));
+
+  uint32_t nd02 = PointToPointIpv4Topology::AddNetDevice (n0,
+    link02);
+
+  Ptr<PointToPointChannel> link03 = 
+    PointToPointIpv4Topology::CreateChannel (DataRate (38400), 
+    MilliSeconds (20));
+
+  uint32_t nd03 = PointToPointIpv4Topology::AddNetDevice (n0,
+    link03);
+
+  Ptr<PointToPointChannel> link04 = 
+    PointToPointIpv4Topology::CreateChannel (DataRate (38400), 
+    MilliSeconds (20));
+
+  uint32_t nd04 = PointToPointIpv4Topology::AddNetDevice (n0, 
+    link04);
+
+  Ptr<PointToPointChannel> link05 = 
+    PointToPointIpv4Topology::CreateChannel (DataRate (38400), 
+    MilliSeconds (20));
+
+  uint32_t nd05 = PointToPointIpv4Topology::AddNetDevice (n0,
+    link05);
+
+  Ptr<PointToPointChannel> link06 = 
+    PointToPointIpv4Topology::CreateChannel (DataRate (38400), 
+    MilliSeconds (20));
+
+  uint32_t nd06 = PointToPointIpv4Topology::AddNetDevice (n0, link06);
+
+  uint32_t nd1 = PointToPointIpv4Topology::AddNetDevice (n1, link01);
+  uint32_t nd2 = PointToPointIpv4Topology::AddNetDevice (n2, link02);
+  uint32_t nd3 = PointToPointIpv4Topology::AddNetDevice (n3, link03);
+  uint32_t nd4 = PointToPointIpv4Topology::AddNetDevice (n4, link04);
+  uint32_t nd5 = PointToPointIpv4Topology::AddNetDevice (n5, link05);
+  uint32_t nd6 = PointToPointIpv4Topology::AddNetDevice (n6, link06);
+
+  PointToPointIpv4Topology::AddAddress (n0, nd01, "10.1.1.1", 
+    "255.255.255.252");
+
+  PointToPointIpv4Topology::AddAddress (n1, nd1, "10.1.1.2", 
+    "255.255.255.252");
+
+  PointToPointIpv4Topology::AddAddress (n0, nd02, "10.1.2.1", 
+    "255.255.255.252");
+
+  PointToPointIpv4Topology::AddAddress (n2, nd2, "10.1.2.2", 
+    "255.255.255.252");
+
+  PointToPointIpv4Topology::AddAddress (n0, nd03, "10.1.3.1", 
+    "255.255.255.252");
+
+  PointToPointIpv4Topology::AddAddress (n3, nd3, "10.1.2.2", 
+    "255.255.255.252");
+
+  PointToPointIpv4Topology::AddAddress (n0, nd04, "10.1.4.1", 
+    "255.255.255.252");
+
+  PointToPointIpv4Topology::AddAddress (n4, nd4, "10.1.4.2", 
+    "255.255.255.252");
+
+  PointToPointIpv4Topology::AddAddress (n0, nd05, "10.1.5.1", 
+    "255.255.255.252");
+
+  PointToPointIpv4Topology::AddAddress (n5, nd5, "10.1.5.2", 
+    "255.255.255.252");
+
+  PointToPointIpv4Topology::AddAddress (n0, nd06, "10.1.6.1", 
+    "255.255.255.252");
+
+  PointToPointIpv4Topology::AddAddress (n6, nd6, "10.1.6.2", 
+    "255.255.255.252");
+
+  uint16_t port = 7;
+
+  Ptr<UdpEchoClient> client = Create<UdpEchoClient> (n0, "10.1.1.2", port, 
+    1, Seconds(1.), 1024);
+
+  Ptr<UdpEchoServer> server = Create<UdpEchoServer> (n1, port);
+
+  server->Start(Seconds(1.));
+  client->Start(Seconds(2.));
+
+  server->Stop (Seconds(10.));
+  client->Stop (Seconds(10.));
+
+  AsciiTrace asciitrace ("tutorial.tr");
+  asciitrace.TraceAllQueues ();
+  asciitrace.TraceAllNetDeviceRx ();
+
+  Simulator::Run ();
+  Simulator::Destroy ();
+}
+@end verbatim
+
+@subsection Routing
+If you are really excited about this simulator you may have already tried to
+modify the scripts outside the tutorial.  I know that one of the first things
+that would have occurred to me when I saw the star network would have been to
+start trying to add applications to echo packets from nodes other than zero.
+If you tried, for example, to start the echo client on node one instead of
+node zero, you would have found an empty trace file.  The reason for this
+is that you have now created an internetwork.  This means you will need to 
+enable internetwork routing.
+
+We have provided a file for you in the @code{tutorial} directory called 
+@code{star-routing.cc} to show you how this is done.  This extremely
+tricky and difficult change is shown below:
+
+@verbatim 
+ GlobalRouteManager::PopulateRoutingTables ();
+@end verbatim
+
+This one-line addition, located just before the simulation runs, tells the 
+@command{ns-3} @emph{global route manager} to walk the topology you created and 
+build internetwork routing tables for all of the nodes in the simulation.
+We changed the client application so that it runs on node four:
+
+@verbatim
+  Ptr<UdpEchoClient> client = Create<UdpEchoClient> (n4, "10.1.1.2", port,
+    1, Seconds(1.), 1024);
+@end verbatim
+
+Now if you build and run @code{star-routing.cc} you can examine the
+@code{tutorial.tr} file and see that your UDP echo packets are now correctly
+routed through the topology.
+
+@section A Dumbbell Network
+One of the most interesting simple topologies (from a phenomenological point of
+view) is commonly called a dumbbell network.  The name derives from a 
+superficial similarity in form to a piece of exercise equipment.
+
+The dumbbell model is typically composed of two bus or star network elements
+connected via a point-to-point link.  The point-to-point link is usually 
+configured with a lower bandwidth than the bus elements to provide a 
+@emph{choke point}.
+
+The following is a representation of the topology.
+
+@sp 1
+@center @image{dumbbell,,,,png}
+
+We have provided a file that constructs this dumbbell network and creates 
+enough data flowing across the choke point that some packets will be dropped.
+The file is called @code{linear-dumbbell.cc} and is located in the 
+@code{tutorial} directory.  We have already covered all of the code used to
+create this network, so we will just quickly go over the main sections of the
+script.
+
+The first section creates a CSMA lan that will become the left side of the
+dumbbell network.  This code should be very familiar since we used the same
+process to create our first example.
+
+@verbatim
+//
+// Create the lan on the left side of the dumbbell.
+//
+  Ptr<Node> n0 = Create<InternetNode> ();
+  Ptr<Node> n1 = Create<InternetNode> ();
+  Ptr<Node> n2 = Create<InternetNode> ();
+  Ptr<Node> n3 = Create<InternetNode> ();
+
+  Ptr<CsmaChannel> lan1 = 
+    CsmaTopology::CreateCsmaChannel (DataRate (10000000), MilliSeconds (2));
+
+  uint32_t nd0 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n0, lan1, 
+    "08:00:2e:00:00:00");
+
+  uint32_t nd1 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n1, lan1, 
+    "08:00:2e:00:00:01");
+
+  uint32_t nd2 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n2, lan1, 
+    "08:00:2e:00:00:02");
+
+  uint32_t nd3 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n3, lan1, 
+    "08:00:2e:00:00:03");
+
+  CsmaIpv4Topology::AddIpv4Address (n0, nd0, "10.1.1.1", "255.255.255.0");
+  CsmaIpv4Topology::AddIpv4Address (n1, nd1, "10.1.1.2", "255.255.255.0");
+  CsmaIpv4Topology::AddIpv4Address (n2, nd2, "10.1.1.3", "255.255.255.0");
+  CsmaIpv4Topology::AddIpv4Address (n3, nd3, "10.1.1.4", "255.255.255.0");
+@end verbatim
+
+The code to generate the CSMA lan on the right side is similar; only the names
+have been changed.
+ 
+@verbatim
+//
+// Create the lan on the right side of the dumbbell.
+//
+  Ptr<Node> n4 = Create<InternetNode> ();
+  Ptr<Node> n5 = Create<InternetNode> ();
+  Ptr<Node> n6 = Create<InternetNode> ();
+  Ptr<Node> n7 = Create<InternetNode> ();
+
+  Ptr<CsmaChannel> lan2 = 
+    CsmaTopology::CreateCsmaChannel (DataRate (10000000), MilliSeconds (2));
+
+  uint32_t nd4 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n4, lan2, 
+    "08:00:2e:00:00:04");
+
+  uint32_t nd5 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n5, lan2, 
+    "08:00:2e:00:00:05");
+
+  uint32_t nd6 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n6, lan2, 
+    "08:00:2e:00:00:06");
+
+  uint32_t nd7 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n7, lan2, 
+    "08:00:2e:00:00:07");
+
+  CsmaIpv4Topology::AddIpv4Address (n4, nd4, "10.1.2.1", "255.255.255.0");
+  CsmaIpv4Topology::AddIpv4Address (n5, nd5, "10.1.2.2", "255.255.255.0");
+  CsmaIpv4Topology::AddIpv4Address (n6, nd6, "10.1.2.3", "255.255.255.0");
+  CsmaIpv4Topology::AddIpv4Address (n7, nd7, "10.1.2.4", "255.255.255.0");
+@end verbatim
+
+Next, we create a point to point link to connect the two lans.  We connect
+the point-to-point channel between nodes three (on the left lan) and four
+(on the right lan).  You should recoginze this as substantially similar to
+the link setup from the @code{point-to-point} example.
+
+@verbatim
+//
+// Create the point-to-point link to connect the two lans.
+//
+  Ptr<PointToPointChannel> link = PointToPointTopology::AddPointToPointLink (
+    n3, n4, DataRate (38400), MilliSeconds (20));
+
+  PointToPointTopology::AddIpv4Addresses (link, n3, "10.1.3.1", 
+    n4, "10.1.3.2");
+@end verbatim
+
+Then we configure data flows.  We create four echo clients that send UDP 
+packets from the left side lan to servers created on the right side lan.
+Notice that we send 100 packets with an inter-packet gap of ten milliseconds
+instead of the single packet we have previously used.  This data rate is
+sufficient to saturate the point-to-point link and will cause packets to be
+dropped when the queue on the link net devices overflows (the default maximum
+queue depth is 100 packets).  Note that we stagger the start of the echo 
+clients to slowly bring up the data rates.
+
+@verbatim
+//
+// Create data flows across the link:
+//   n0 ==> n4 ==> n0
+//   n1 ==> n5 ==> n1
+//   n2 ==> n6 ==> n2
+//   n3 ==> n7 ==> n3
+//
+  uint16_t port = 7;
+
+  Ptr<UdpEchoClient> client0 = Create<UdpEchoClient> (n0, "10.1.2.1", port, 
+    100, Seconds(.01), 1024);
+  Ptr<UdpEchoClient> client1 = Create<UdpEchoClient> (n1, "10.1.2.2", port, 
+    100, Seconds(.01), 1024);
+  Ptr<UdpEchoClient> client2 = Create<UdpEchoClient> (n2, "10.1.2.3", port, 
+    100, Seconds(.01), 1024);
+  Ptr<UdpEchoClient> client3 = Create<UdpEchoClient> (n3, "10.1.2.4", port, 
+    100, Seconds(.01), 1024);
+
+  Ptr<UdpEchoServer> server4 = Create<UdpEchoServer> (n4, port);
+  Ptr<UdpEchoServer> server5 = Create<UdpEchoServer> (n5, port);
+  Ptr<UdpEchoServer> server6 = Create<UdpEchoServer> (n6, port);
+  Ptr<UdpEchoServer> server7 = Create<UdpEchoServer> (n7, port);
+
+  server4->Start(Seconds(1.));
+  server5->Start(Seconds(1.));
+  server6->Start(Seconds(1.));
+  server7->Start(Seconds(1.));
+
+  client0->Start(Seconds(2.));
+  client1->Start(Seconds(2.1));
+  client2->Start(Seconds(2.2));
+  client3->Start(Seconds(2.3));
+
+  server4->Stop (Seconds(10.));
+  server5->Stop (Seconds(10.));
+  server6->Stop (Seconds(10.));
+  server7->Stop (Seconds(10.));
+
+  client0->Stop (Seconds(10.));
+  client1->Stop (Seconds(10.));
+  client2->Stop (Seconds(10.));
+  client3->Stop (Seconds(10.));
+@end verbatim
+
+The remainder of the file should be quite familiar to you.  Go ahead and 
+run @code{linear-dumbbell}.  Now take a look at the trace (@code{tutorial.tr})
+file.  You will now see trace lines that begin with @code{d}.  Alternatively 
+you can search for the string ``queue-drop'' which is the expansion of the 
+drop code.
+
+Interpretation of a dropped packet is straightforward.  We have expanded
+the first @code{queue-drop} trace for you below.  See the section on ASCII 
+tracing for details.
+
+@verbatim
+  00 d 
+  01 2.40938 
+  02 nodeid=3 
+  03 device=1 
+  04 queue-drop 
+  05 pkt-uid=124 
+  06 LLCSNAP(type 0x800) 
+  07   IPV4(
+  08     tos 0x0 
+  09     ttl 63 
+  10     id 20 
+  11     offset 0 
+  12     flags [none] 
+  13     length: 1052) 10.1.1.3 > 10.1.2.3 
+  14     UDP(length: 1032) 
+  15       49153 > 7 
+  16       DATA (length 1024)
+@end verbatim
+
+We leave it as an exercise to examine the trace files in more detail.
+
+@c ========================================================================
+@c Nonlinear Thinking
+@c ========================================================================
+
+@node Nonlinear-Thinking
+@chapter Nonlinear Thinking
+
+One thing that all of our examples so far have in common is that they are
+composed of a linear collection of calls into the @command{ns-3} system.  The
+programmers among the readers may have wondered why there is not as much
+as a for-loop in all of the examples.  The answer is that we wanted to 
+introduce you to @command{ns-3} scripting with a minimum of conceptual 
+overhead.  We're going to remedy that situation shortly.
+
+We have written a number of @command{ns-3} scripts in C++.  Although we have 
+been perfectly linear in our script implementations, just like any other C++ 
+program, an @command{ns-3} script can use any features of the language you
+desire.  If you will look back at the @code{linear-dumbbell.cc}
+example, you may notice that the code to create the left and right sides of
+the dumbbell is operationally identical -- only the names change.  An obvious
+improvement of this program would be to use subroutines to create the sides.
+Since we are working with C++, we should probably do this in an 
+object-oriented way.  Since object-oriented design is somewhat of a black art
+to some people, we'll take some time here and outline a simple methodology 
+you can follow.
+
+@section Object Design 101 -- Class Ipv4BusNetwork
+If you are a master of object oriented design, feel free to skip or skim this
+section, in which we derive a simplistic but fully operational bus network 
+class.
+
+So you want to create a BusNetwork class.  Often the biggest hurdle in a 
+design is figuring out how to get started.  One of the simplest and most 
+straightforward ways to do an object decomposition of a problem is to simply 
+write down a description of the problem and take a look at the words 
+you used.  Let's take some time and do that, first at a very high level.
+
+@example
+A bus network is an implementation of a particular network topology that
+contains some number of nodes.  Each of these nodes is attached to a single 
+multi-drop channel.  The network itself has some attributes independent of
+the topology such as a network mask, network number (prefix) and base IP
+address.
+@end example
+
+The first thing to do is to focus on the nouns and adjectives.  These will
+give you a starting point for required classes and member variables.
+
+Immediately we can notice that at the highest level we are talking about the
+noun @emph{network}.  This probably won't surprise you.  We also have an 
+adjective that modifies the noun -- @emph{bus}.  This should lead us to our 
+first class defintion.  Usually class names are constructed in the same way
+as an English language sentence would be spoken.  For example, one would speak
+of a @emph{bus network} in conversation, so we would normally create a
+@code{class BusNetwork} to represent it.  
+
+One thing to note is that we have used two words in our description quite 
+naturally: @emph{is} and @emph{has}.  When you see these words should should
+immediately think of the object-oriented concepts of @emph{ISA} (inheritance)
+and @emph{HASA} (containment) respectively.  We wrote that a bus network
+@emph{is} an implementation of a particular network topology.  Perhaps you 
+will agree that there is a natural base class called @code{Network} that 
+@emph{has} the attributes discussed above.  The fact that a @code{BusNetwork}
+@emph{ISA} kind of @code{Network} suggests inheritance.  Let's capture that 
+thought right away remembering that we're focused on IP version four here:
+
+@verbatim
+  class Ipv4Network
+  {
+  public:
+    Ipv4Address m_network;
+    Ipv4Mask m_mask;
+    Ipv4Address m_baseAddress;
+  };
+
+  class Ipv4BusNetwork : public Ipv4Network
+  {
+  };
+@end verbatim
+
+Let's take a look at the @emph{HASA} relationships of the bus network.  Clearly
+it will @emph{have} a reference to the underlying channel that implements the
+actual communications medium.  We use smart pointers for those references, so 
+one member variable is obvious:
+
+@verbatim
+  Ptr<CsmaChannel> m_channel;
+@end verbatim
+
+A bus network will also need to contain references to all of the nodes we
+eventually want to create.  If you are working in C++ and see the words contain
+or container, you should immediately think of the Standard Template Library
+or STL.  A quick search of the available containers there will probably lead
+you to consider the vector class.  A vector is a container that looks like an
+array.  This is just what we need here.  Again, we want to use smart pointers
+to reference our nodes, so the declaration of the vector would look like,
+
+@verbatim
+  std::vector<Ptr<Node> > m_nodes;
+@end verbatim
+
+It will save you headaches in the future if you notice that the space between
+the two right brackets is required to differentiate this situation from a
+right-shift operator.  So we have a pretty good start already after just a
+little work.  Now we need to turn our attention to actions.  Let's write 
+another little description of the things you consider doing to a Bus network.
+
+@example
+We need to be able to create a bus network.  We need to be able to delete a
+bus network.  We need to be able to get a handle to a node in order to add
+applications.  We need to be able to set the network, mask and base address
+somehow, specify how many nodes to create and provide the underlying channel
+its required bandwidth and delay parameters.
+@end example
+
+We now look at the @emph{verbs} in that sentence.  These will give a good 
+starting point for the methods of the classes.  For example, the verbs 
+@emph{create} and @emph{delete} should suggest @emph{constructor} and 
+@emph{destructor}.  The verb @emph{get} leads us to providing a method called
+@code{GetNode}.  We have to provide a number of parameters so we can either
+provide @emph{setters} or we can simply pass them in as parameters to our
+constructors.  Since this is a simple example, we won't bother to implement
+getters and setters (methods to get and set member variables to enhance data
+hiding).  Let's use this guidance to finish up our class declarations:
+
+@verbatim
+  class Ipv4Network
+  {
+  public:
+    Ipv4Network (Ipv4Address network, Ipv4Mask mask, Ipv4Address address);
+    virtual ~Ipv4Network ();
+
+    Ipv4Address m_network;
+    Ipv4Mask m_mask;
+    Ipv4Address m_baseAddress;
+  };
+
+  class Ipv4BusNetwork : public Ipv4Network
+  {
+  public:
+    Ipv4BusNetwork (
+      Ipv4Address   network, 
+      Ipv4Mask      mask, 
+      Ipv4Address   startAddress, 
+      DataRate      bps, 
+      Time          delay, 
+      uint32_t      n);
+
+    virtual ~Ipv4BusNetwork ();
+
+    Ptr<Node> GetNode (uint32_t n);
+
+  private:
+    std::vector<Ptr<Node> > m_nodes;
+    Ptr<CsmaChannel> m_channel;
+  };
+@end verbatim
+
+That's it.  We have actually already walked through almost all of the code
+required to construct a bus network in our @code{csma-echo.cc} 
+example, so let's just jump forward and take a look at an implementation
+of this thing.  We provide an implementation for you in the files 
+@code{ipv4-bus-network.h} and @code{ipv4-bus-network.cc} located in the
+@code{tutorial} directory.  We also provide an example that uses the new
+class in the file @code{bus-network.cc}.
+
+The interesting method from our current perspective is the Ipv4BusNetwork
+constructor, shown below:
+
+@verbatim
+  Ipv4BusNetwork::Ipv4BusNetwork (
+    Ipv4Address   network, 
+    Ipv4Mask      mask, 
+    Ipv4Address   baseAddress, 
+    DataRate      bps, 
+    Time          delay, 
+    uint32_t      n)
+  : 
+    Ipv4Network (network, mask, baseAddress)
+  {
+    Ipv4AddressGenerator::SeedNetwork (mask, network);
+    Ipv4AddressGenerator::SeedAddress (mask, baseAddress);
+  
+    m_channel = CsmaTopology::CreateCsmaChannel (bps, delay);
+  
+    for (uint32_t i = 0; i < n; ++i)
+      {
+        Ptr<Node> node = Create<InternetNode> ();
+        uint32_t nd = CsmaIpv4Topology::AddIpv4CsmaNetDevice (node, m_channel, 
+          Mac48Address::Allocate ());
+        Ipv4Address address = Ipv4AddressGenerator::AllocateAddress (mask, 
+          network);
+        CsmaIpv4Topology::AddIpv4Address (node, nd, address, mask);
+        m_nodes.push_back (node);
+      }
+  }
+@end verbatim
+
+Notice that we do the simple and straightforward thing and pass all of our
+parameters to the constructor.  For those unfamiliar with C++, the line after
+the colon and before the opening brace (shown below),
+
+@verbatim
+  : 
+    Ipv4Network (network, mask, baseAddress)
+  {
+@end verbatim
+
+Passes the appropriate parameters to the constructor of the base class
+@code{Ipv4Network}.  There are two new calls that we haven't seen immediately
+after this initialization.  They are:
+
+@verbatim
+    Ipv4AddressGenerator::SeedNetwork (mask, network);
+    Ipv4AddressGenerator::SeedAddress (mask, baseAddress);
+@end verbatim
+
+We provide an IP address generator class to allow us to programatically 
+allocate IP addresses.  The first call to @code{SeedNetwork} gives the
+address generator a starting network number to use when generating addresses.
+The second call to @code{SeedAddress} gives the address generator a starting
+IP address to use.  There is a starting network and starting address for each
+of the 32 possible network masks.  Later in the for loop, you will see a
+call to @code{AllocateAddress} in which the IP address for each node created
+in the loop is actually generated.  
+
+The only unfamiliar call in the reset of the constructor will be:
+
+@verbatim
+  m_nodes.push_back (node);
+@end verbatim
+
+This is the STL code to add the newly created node to the vector of nodes
+attached to the bus.  
+
+For your convenience, we reproduce the entire bus network implementation below:
+
+@verbatim
+  /* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+  /*
+   * Copyright (c) 2007 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 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/mac48-address.h"
+  #include "ns3/csma-net-device.h"
+  #include "ns3/csma-topology.h"
+  #include "ns3/csma-ipv4-topology.h"
+  
+  #include "ipv4-bus-network.h"
+  #include "ipv4-address-generator.h"
+  
+  namespace ns3 {
+  
+  Ipv4Network::Ipv4Network (
+    Ipv4Address   network, 
+    Ipv4Mask      mask, 
+    Ipv4Address   address)
+  : 
+    m_network (network), m_mask (mask), m_baseAddress (address)
+  {
+  }
+  
+  Ipv4Network::~Ipv4Network ()
+  {
+  }
+  
+  Ipv4BusNetwork::Ipv4BusNetwork (
+    Ipv4Address   network, 
+    Ipv4Mask      mask, 
+    Ipv4Address   baseAddress, 
+    DataRate      bps, 
+    Time          delay, 
+    uint32_t      n)
+  : 
+    Ipv4Network (network, mask, baseAddress)
+  {
+    Ipv4AddressGenerator::SeedNetwork (mask, network);
+    Ipv4AddressGenerator::SeedAddress (mask, baseAddress);
+  
+    m_channel = CsmaTopology::CreateCsmaChannel (bps, delay);
+  
+    for (uint32_t i = 0; i < n; ++i)
+      {
+        Ptr<Node> node = Create<InternetNode> ();
+        uint32_t nd = CsmaIpv4Topology::AddIpv4CsmaNetDevice (node, m_channel, 
+          Mac48Address::Allocate ());
+        Ipv4Address address = Ipv4AddressGenerator::AllocateAddress (mask, 
+          network);
+        CsmaIpv4Topology::AddIpv4Address (node, nd, address, mask);
+        m_nodes.push_back (node);
+      }
+  }
+  
+  Ipv4BusNetwork::~Ipv4BusNetwork ()
+  {
+  }
+  
+    Ptr<Node>
+  Ipv4BusNetwork::GetNode (uint32_t n)
+  {
+    return m_nodes[n];
+  }
+  
+  }; // namespace ns3
+@end verbatim
+
+@section Using Ipv4BusNetwork
+If all you ever want to do with a bus network can be captured in a topology
+with four nodes on the bus, the preceeding section may seem like a colossal
+waste of time.  This is probably not the case, though.  Now that we have a
+relatively abstract bus class, we can create bus networks with 4, 40 or 4000
+nodes with no additional effort.
+
+A use of the bus network class is shown in the file 
+@code{bus-netowrk.cc} located in the @code{tutorial} directory.  The
+interesting code is,
+
+@verbatim
+  Ipv4BusNetwork bus ("10.1.0.0", "255.255.0.0", "0.0.0.3",
+    DataRate(10000000), MilliSeconds(20), 10);
+@end verbatim
+
+Here we create a bus network with the network number ``10.1.0.0'' and the 
+network mask ``255.255.0.0'' that completes the IP network definition.  You 
+can consider these together as ``10.1.0.0/16'' if you prefer.  The next 
+parameter tells the bus to start numbering IP addresses of contained nodes at
+``10.1.0.3'' (remember the network number will be combined).  We provided a
+data rate of 10 megabits per second and a latency of 20 milliseconds.  
+Finally, we ask the @code{Ipv4BusNetwork} object to create ten nodes in the
+network.
+
+If you are feeling brave, go ahead and change the number of nodes to be 100,
+1000, 10,000 or more to generate larger and larger networks.  Before you go 
+too far, remember that a trace file will be generated when you run your 
+resulting program and ee asked the trace facility to trace all net device 
+receive events.  This will include the reception of the broadcast ARP request 
+by all of the nodes in the simulation, so this can add up quickly.
+
+@c ========================================================================
+@c Summary
+@c ========================================================================
+
+@node Summary
+@chapter Summary
+
+This concludes the first part of the tutorial.  We have focused on
+using the @command{ns-3} system to construct various network topologies and to
+simulate sendng data across the networks; and we've shown you how to use the 
+trace facility to get access to simulation results.
+
+We now encourage you to play with the system a little.  Experiment with what
+we have provided.  Build a hierarchical network simulation.  Perhaps exercise
+your object design skills and create a new @code{Ipv4DumbbellNetwork} class 
+to create dumbbell networks using the Ipv4BusNetwork class we just created.
+Hint:  An Ipv4DumbbellNetwork @emph{has} two @code{Ipv4BusNetwork} objects; 
+a left side and a right side.
+
+In the next part of the tutorial we are going to drop down a level and begin
+examining the lower levels of the system in more detail.  We are going to
+explain how to change the behavior of the system and eventually how to write
+new models and applications.  This is a good time to make sure that you
+thorougly understand what we've gone over so far.
+
+@c ========================================================================
+@c Doxygen
+@c ========================================================================
+
+@node The-Doxygen-Documentation-System
+@chapter The Doxygen Documentation System
+
+@node How-To-Change-Things
+@chapter How to Change Things
+
+@node How-To-Set-Default-Values
+@chapter How to Set Default Values
+
+@node How-To-Write-A-New-Application
+@chapter How to Write a New Application
+
+@printindex cp
+
+@bye