From f2a0ca2b0e8527e09c32b9ba870d7bf44175c6af Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Thu, 13 Dec 2007 23:50:16 -0800 Subject: [PATCH] put updated tutorial.texi in doc directory --- doc/tutorial/dumbbell.png | Bin 0 -> 8155 bytes doc/tutorial/pp.png | Bin 0 -> 2658 bytes doc/tutorial/star.png | Bin 0 -> 7803 bytes doc/tutorial/tutorial.texi | 3498 ++++++++++++++++++++++++++++++++++++ 4 files changed, 3498 insertions(+) create mode 100755 doc/tutorial/dumbbell.png create mode 100755 doc/tutorial/pp.png create mode 100755 doc/tutorial/star.png create mode 100755 doc/tutorial/tutorial.texi diff --git a/doc/tutorial/dumbbell.png b/doc/tutorial/dumbbell.png new file mode 100755 index 0000000000000000000000000000000000000000..0fc3d8c9e040ec281338b50c4ade95b1037a17e0 GIT binary patch literal 8155 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 literal 0 HcmV?d00001 diff --git a/doc/tutorial/pp.png b/doc/tutorial/pp.png new file mode 100755 index 0000000000000000000000000000000000000000..84b76d6df2163bcc264f6728f4ebd87244493bb8 GIT binary patch literal 2658 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./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