diff --git a/doc/tutorial/dumbbell.png b/doc/tutorial/dumbbell.png new file mode 100755 index 000000000..0fc3d8c9e Binary files /dev/null and b/doc/tutorial/dumbbell.png differ diff --git a/doc/tutorial/pp.png b/doc/tutorial/pp.png new file mode 100755 index 000000000..84b76d6df Binary files /dev/null and b/doc/tutorial/pp.png differ diff --git a/doc/tutorial/star.png b/doc/tutorial/star.png new file mode 100755 index 000000000..c580d0305 Binary files /dev/null and b/doc/tutorial/star.png differ diff --git a/doc/tutorial/tutorial.texi b/doc/tutorial/tutorial.texi new file mode 100755 index 000000000..799ea87b0 --- /dev/null +++ b/doc/tutorial/tutorial.texi @@ -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 p = Create (); +@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 p = Create (); +@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 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 + 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 (x, y); +@end verbatim + +@cindex template!instantiate +When the compiler sees @code{Add} it understands that it needs to make +sure that code is instantiated (created) to perform the @code{Add} using the +specified type @code{}. 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 (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 + 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 void MyStack::Push (T data) + { + ... + }; +@end verbatim + +You can then use the new templated class in the following way, + +@verbatim + int x, y; + + MyStack 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{}. + +@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 p = ... +@end verbatim + +To a first approximation, you can think of @code{Ptr} 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} 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} and @code{Ptr}, +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 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 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 (); +@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()} 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}). 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 (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 (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 p = Create (); +@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} smart pointer. For this assignment of a +@code{Ptr} to a @code{Ptr} 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}. +This operator takes a reference to a @code{Ptr} and not a reference to +a @code{Ptr}. 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 p = Create (); +@end verbatim + +or, + +@verbatim + Ptr p = Create (); +@end verbatim + +will work just fine. Of course, if you try something @emph{bad} (TM), like: + +@verbatim + Ptr p = Create (); +@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 p = Create (); +@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 n0 = Create (); + Ptr n1 = Create (); + Ptr n2 = Create (); + Ptr n3 = Create (); +@end verbatim + +As we now understand, this will create four @code{InternetNode} objects on +the heap and create four @code{Ptr} 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 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 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 n0 = Create (); + Ptr n1 = Create (); + Ptr n2 = Create (); + Ptr n3 = Create (); + + Ptr 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 client = Create (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 client = Create (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 client = Create (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 client = Create (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 server = Create (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 n0 = Create (); + Ptr n1 = Create (); + Ptr n2 = Create (); + Ptr n3 = Create (); + + Ptr 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 client = Create (n0, "10.1.1.2", port, + maxPacketCount, interPacketInterval, packetSize); + + Ptr server = Create (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 n0 = Create (); + Ptr n1 = Create (); + Ptr n2 = Create (); + Ptr n3 = Create (); + + Ptr 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 client = Create (n0, "10.1.1.2", port, + maxPacketCount, interPacketInterval, packetSize); + + Ptr server = Create (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 n0 = Create (); + Ptr n1 = Create (); + + Ptr 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 n0 = Create (); + Ptr n1 = Create (); + + Ptr 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 client = Create (n0, "10.1.1.2", port, + 1, Seconds(1.), 1024); + + Ptr server = Create (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 n0 = Create (); + Ptr n1 = Create (); + Ptr n2 = Create (); + Ptr n3 = Create (); + Ptr n4 = Create (); + Ptr n5 = Create (); + Ptr n6 = Create (); +@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 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 n0 = Create (); + Ptr n1 = Create (); + Ptr n2 = Create (); + Ptr n3 = Create (); + Ptr n4 = Create (); + Ptr n5 = Create (); + Ptr n6 = Create (); + + Ptr link01 = + PointToPointIpv4Topology::CreateChannel (DataRate (38400), + MilliSeconds (20)); + + uint32_t nd01 = PointToPointIpv4Topology::AddNetDevice (n0, + link01); + + Ptr link02 = + PointToPointIpv4Topology::CreateChannel (DataRate (38400), + MilliSeconds (20)); + + uint32_t nd02 = PointToPointIpv4Topology::AddNetDevice (n0, + link02); + + Ptr link03 = + PointToPointIpv4Topology::CreateChannel (DataRate (38400), + MilliSeconds (20)); + + uint32_t nd03 = PointToPointIpv4Topology::AddNetDevice (n0, + link03); + + Ptr link04 = + PointToPointIpv4Topology::CreateChannel (DataRate (38400), + MilliSeconds (20)); + + uint32_t nd04 = PointToPointIpv4Topology::AddNetDevice (n0, + link04); + + Ptr link05 = + PointToPointIpv4Topology::CreateChannel (DataRate (38400), + MilliSeconds (20)); + + uint32_t nd05 = PointToPointIpv4Topology::AddNetDevice (n0, + link05); + + Ptr 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 client = Create (n0, "10.1.1.2", port, + 1, Seconds(1.), 1024); + + Ptr server = Create (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 client = Create (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 n0 = Create (); + Ptr n1 = Create (); + Ptr n2 = Create (); + Ptr n3 = Create (); + + Ptr 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 n4 = Create (); + Ptr n5 = Create (); + Ptr n6 = Create (); + Ptr n7 = Create (); + + Ptr 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 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 client0 = Create (n0, "10.1.2.1", port, + 100, Seconds(.01), 1024); + Ptr client1 = Create (n1, "10.1.2.2", port, + 100, Seconds(.01), 1024); + Ptr client2 = Create (n2, "10.1.2.3", port, + 100, Seconds(.01), 1024); + Ptr client3 = Create (n3, "10.1.2.4", port, + 100, Seconds(.01), 1024); + + Ptr server4 = Create (n4, port); + Ptr server5 = Create (n5, port); + Ptr server6 = Create (n6, port); + Ptr server7 = Create (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 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 > 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 GetNode (uint32_t n); + + private: + std::vector > m_nodes; + Ptr 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 = Create (); + 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 = Create (); + 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 + 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