From 5cf2aa1ebff8ce474928d943203d4931231e858d Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Sat, 28 Jun 2008 19:46:55 -0700 Subject: [PATCH] swap in new tutorial --- doc/tutorial/building-topologies.texi | 300 ++++++ doc/tutorial/conceptual-overview.texi | 809 +++++++++++++++ doc/tutorial/getting-started.texi | 275 +++++ doc/tutorial/{ => in-process}/Makefile | 0 doc/tutorial/{ => in-process}/attributes.texi | 0 doc/tutorial/{ => in-process}/figures/README | 0 .../{ => in-process}/figures/dumbbell.dia | Bin .../{ => in-process}/figures/helpers.obj | 0 .../{ => in-process}/figures/oneobj.png | Bin doc/tutorial/{ => in-process}/figures/pp.dia | Bin .../{ => in-process}/figures/star.dia | Bin .../{ => in-process}/figures/threeobj.png | Bin doc/tutorial/{ => in-process}/helpers.texi | 0 .../{ => in-process}/introduction.texi | 0 doc/tutorial/{ => in-process}/log.texi | 0 doc/tutorial/{ => in-process}/other.texi | 0 doc/tutorial/{ => in-process}/output.texi | 0 doc/tutorial/{ => in-process}/statistics.texi | 0 .../{ => in-process}/troubleshoot.texi | 0 doc/tutorial/in-process/tutorial.css | 156 +++ doc/tutorial/in-process/tutorial.texi | 105 ++ doc/tutorial/tutorial.texi | 31 +- doc/tutorial/tweaking.texi | 978 ++++++++++++++++++ examples/hello-simulator.cc | 27 + 24 files changed, 2660 insertions(+), 21 deletions(-) create mode 100644 doc/tutorial/building-topologies.texi create mode 100644 doc/tutorial/conceptual-overview.texi create mode 100644 doc/tutorial/getting-started.texi rename doc/tutorial/{ => in-process}/Makefile (100%) rename doc/tutorial/{ => in-process}/attributes.texi (100%) rename doc/tutorial/{ => in-process}/figures/README (100%) rename doc/tutorial/{ => in-process}/figures/dumbbell.dia (100%) rename doc/tutorial/{ => in-process}/figures/helpers.obj (100%) rename doc/tutorial/{ => in-process}/figures/oneobj.png (100%) rename doc/tutorial/{ => in-process}/figures/pp.dia (100%) rename doc/tutorial/{ => in-process}/figures/star.dia (100%) rename doc/tutorial/{ => in-process}/figures/threeobj.png (100%) rename doc/tutorial/{ => in-process}/helpers.texi (100%) rename doc/tutorial/{ => in-process}/introduction.texi (100%) rename doc/tutorial/{ => in-process}/log.texi (100%) rename doc/tutorial/{ => in-process}/other.texi (100%) rename doc/tutorial/{ => in-process}/output.texi (100%) rename doc/tutorial/{ => in-process}/statistics.texi (100%) rename doc/tutorial/{ => in-process}/troubleshoot.texi (100%) create mode 100644 doc/tutorial/in-process/tutorial.css create mode 100644 doc/tutorial/in-process/tutorial.texi create mode 100644 doc/tutorial/tweaking.texi create mode 100644 examples/hello-simulator.cc diff --git a/doc/tutorial/building-topologies.texi b/doc/tutorial/building-topologies.texi new file mode 100644 index 000000000..a78531b11 --- /dev/null +++ b/doc/tutorial/building-topologies.texi @@ -0,0 +1,300 @@ + +@c ======================================================================== +@c Begin document body here +@c ======================================================================== + +@c ======================================================================== +@c PART: Building Topologies +@c ======================================================================== +@c The below chapters are under the major heading "Building Topologies" +@c This is similar to the Latex \part command +@c +@c ======================================================================== +@c Building Topologies +@c ======================================================================== +@node Building Topologies +@chapter Building Topologies + +@menu +* Building a Star Topology +@end menu + +@c ======================================================================== +@c Building a Star Topology +@c ======================================================================== +@node Building a Star Topology +@section Building a Star Topology + +@cindex topology +@cindex topology|star +In this section we are going to use the point-to-point topology primitive we +have explored in quite some detail to construct a star network. In the star, +there is a central node that is connected to other nodes in a ``hub and spoke'' +fashion, with each ``spoke'' being a point-to-point link. + +We provide an example of a star topology simulation script on our +@code{examples} directory. Go ahead and open @code{examples/star.cc} in your +favorite editor. You will have already seen enough ns-3 code to understand +this example, but we will go over the script briefly and examine some of the +output. + +There is an amazingly beautiful bit of ASCII art at the beginning of the file +that shows the topology used in the script. Most ns-3 example programs +provide this, which can be surprisingly useful in understanding the code. + +@verbatim + // Network topology + // + // n3 n2 + // | / + // | / + // n4 --- n0 --- n1 + // / | + // / | + // n5 n6 +@end verbatim + +There are seven nodes in this simulation, nodes zero through six. Node zero is +the hub of this star network. We are going to discover that there will be a +flow of echo packets between node four and node one, between node three and +node six, and node five and node two. + +The script starts by creating seven nodes in a @code{NodeContainer} and +installs internet protocol stacks on all seven. + +@verbatim + int + main (int argc, char *argv[]) + { + NodeContainer nodes; + nodes.Create (7); + + InternetStackHelper stack; + stack.Install (nodes); + + ... +@end verbatim + +It then creates six more @code{NodeContainer}s representing the nodes at each +end of the six spokes. In all cases, the first node in the spoke is node zero. + +@verbatim + NodeContainer nodes0and1 = NodeContainer (nodes.Get (0), nodes.Get (1)); + NodeContainer nodes0and2 = NodeContainer (nodes.Get (0), nodes.Get (2)); + NodeContainer nodes0and3 = NodeContainer (nodes.Get (0), nodes.Get (3)); + NodeContainer nodes0and4 = NodeContainer (nodes.Get (0), nodes.Get (4)); + NodeContainer nodes0and5 = NodeContainer (nodes.Get (0), nodes.Get (5)); + NodeContainer nodes0and6 = NodeContainer (nodes.Get (0), nodes.Get (6)); +@end verbatim + +These node containers will be used during the creation of the point-to-point +links by the @code{PointToPointHelper}. The next bit of code instantiates +a helper and sets the default values for the device @code{DataRate} and the +channel @code{Delay} attributes as we have previously seen. + +@verbatim + PointToPointHelper pointToPoint; + pointToPoint.SetDeviceParameter ("DataRate", StringValue ("5Mbps")); + pointToPoint.SetChannelParameter ("Delay", StringValue ("2ms")); +@end verbatim + +The next step is to install the net devices on the nodes referenced by the +six node containers and connect them via channels. We used one instance +of the @code{pointToPoint.Install} method to construct our single +point-to-point link in the @code{first.cc} script. This code just does that +six times between different combinations of nodes. + +@verbatim + NetDeviceContainer devicesOnNodes0and1 = pointToPoint.Install (nodes0and1); + NetDeviceContainer devicesOnNodes0and2 = pointToPoint.Install (nodes0and2); + NetDeviceContainer devicesOnNodes0and3 = pointToPoint.Install (nodes0and3); + NetDeviceContainer devicesOnNodes0and4 = pointToPoint.Install (nodes0and4); + NetDeviceContainer devicesOnNodes0and5 = pointToPoint.Install (nodes0and5); + NetDeviceContainer devicesOnNodes0and6 = pointToPoint.Install (nodes0and6); +@end verbatim + +Note that this does mean that node zero will have six net devices after this +code executes. Recall that we need to keep containers holding the net devices +we created in order to do IP address assignment. This is the next step in the +script. + +Just as in @code{first.cc} we use the Ipv4AddressHelper to make it easy to +deal with addressing. We need to create different networks for each stub, so +we have to call the @code{SetBase} method and provide a different network +number before assigning addresses to the devices on each network. We make it +easy to remember what is what by setting the least significant bits of the +network number to the unique node on the spoke. For example, the spoke between +nodes zero and one is network 10.1.1; and the spoke between nodes zero and +two is 10.1.2, etc. Note that the network mask is set to 255.255.255.252 in +all cases. + +@verbatim + Ipv4AddressHelper ipv4; + + ipv4.SetBase ("10.1.1.0", "255.255.255.252"); + Ipv4InterfaceContainer interfacesOnNodes0and1 = + ipv4.Assign (devicesOnNodes0and1); + + ipv4.SetBase ("10.1.2.0", "255.255.255.252"); + Ipv4InterfaceContainer interfacesOnNodes0and2 = + ipv4.Assign (devicesOnNodes0and2); + + ipv4.SetBase ("10.1.3.0", "255.255.255.252"); + Ipv4InterfaceContainer interfacesOnNodes0and3 = + ipv4.Assign (devicesOnNodes0and3); + + ipv4.SetBase ("10.1.4.0", "255.255.255.252"); + Ipv4InterfaceContainer interfacesOnNodes0and4 = + ipv4.Assign (devicesOnNodes0and4); + + ipv4.SetBase ("10.1.5.0", "255.255.255.252"); + Ipv4InterfaceContainer interfacesOnNodes0and5 = + ipv4.Assign (devicesOnNodes0and5); + + ipv4.SetBase ("10.1.6.0", "255.255.255.252"); + Ipv4InterfaceContainer interfacesOnNodes0and6 = + ipv4.Assign (devicesOnNodes0and6); +@end verbatim + +When the above code has executed, we will have the topology complete and then +need to move on to applications. The code to do this should be familiar to +you, but we have rearranged it slightly. + +We use an ApplicationContainer to hold the results of the helper operations, +and use the UdpEchoServerHelper and UdpEchoClient server to configure the +apps just as we did in the @code{first.cc} script. + +@verbatim + uint16_t port = 9; + + ApplicationContainer apps; + + UdpEchoServerHelper server; + server.SetPort (port); + + UdpEchoClientHelper client; + client.SetAppAttribute ("MaxPackets", UintegerValue (10)); + client.SetAppAttribute ("Interval", StringValue ("10ms")); + client.SetAppAttribute ("PacketSize", UintegerValue (137)); +@end verbatim + +The next section of code is repeated three times, once for each data flow. +We'll skim over the first instance quickly. The other two differ only in +the nodes selected and the starting times of the flows. + +Just as we did in the @code{first.cc} script, we use the +@code{UdpEchoServerHelper} to install the echo server on a node (in this case, +node number one -- the rightmost spoke in the topology). We tell the server +application to start at a simulation time of one second. We use the +@code{UdpEchoClientHelper} to install the echo client on a node (in this case, +node number four -- the leftmost spoke in the topology). We tell the client +to start sending data at a simulation time of two seconds. + +@verbatim + // + // Echo from node 4 to node 1 starting at 2 sec + // + apps = server.Install (nodes.Get (1)); + apps.Start (Seconds (1.0)); + + client.SetRemote (interfacesOnNodes0and1.GetAddress (1), port); + apps = client.Install (nodes.Get (4)); + apps.Start (Seconds (2.0)); +@end verbatim + +The next sections do the same thing, but for nodes three and six with a flow +starting at 2.1 seconds, and for nodes five and two with flow starting at 2.2 +seconds. + +The only piece of code you may not have seen before follows. Since we have +built an internetwork, we need some form of internetwork routing. Ns-3 +provides what we call a global route manager to set up the routing tables on +nodes. This route manager has a global function that runs though the nodes +of the simulation and does the hard work of setting up routing for you. + +Basically, what happens is that each node behaves as if it were an OSPF router +that communicates instantly and magically with all other routers. Each node +generates link advertisements to the global route manager, which uses this +information to construct the routing tables for each node. + +@verbatim + GlobalRouteManager::PopulateRoutingTables (); +@end verbatim + +The remainder of the script should be very familiar to you. We just enable +ASCII and pcap tracing and run the simulation: + +@verbatim + std::ofstream ascii; + ascii.open (``star.tr''); + PointToPointHelper::EnableAsciiAll (ascii); + PointToPointHelper::EnablePcapAll (``star''); + + Simulator::Run (); + Simulator::Destroy (); + } +@end verbatim + +In order to run this example, you use waf. All of our example programs are +built by default, so all you have to do is run it. Now, you did not build +this script by copying it into the scratch directory, so you don't have to +add the scratch directory to the run command. You just do the following, + +@verbatim + ./waf --run star +@end verbatim + +There is no output from this script by default. It will just go off and +silently do its thing. All you will see are waf messages: + +@verbatim + ~/repos/ns-3-tutorial > ./waf --run star + Entering directory `/home/craigdo/repos/ns-3-tutorial/build' + Compilation finished successfully + ~/repos/ns-3-tutorial > +@end verbatim + +If you now go and look in the top level directory, you will find a number of +trace files: + +@verbatim + ~/repos/ns-3-tutorial > ls *.pcap *.tr + star-0-0.pcap star-0-3.pcap star-1-0.pcap star-4-0.pcap star.tr + star-0-1.pcap star-0-4.pcap star-2-0.pcap star-5-0.pcap + star-0-2.pcap star-0-5.pcap star-3-0.pcap star-6-0.pcap + ~/repos/ns-3-tutorial > +@end verbatim + +If you have gone through the tracing section of this tutorial, you know how to +interpret all of these files. For your reading pleasure, we reproduce a +tcpdump from the net device on node four: + +@verbatim + [ns-regression] ~/repos/ns-3-tutorial > tcpdump -r star-4-0.pcap -nn -tt + reading from file star-4-0.pcap, link-type PPP (PPP) + 2.000000 IP 10.1.4.2.49153 > 10.1.1.2.9: UDP, length 137 + 2.009068 IP 10.1.1.2.9 > 10.1.4.2.49153: UDP, length 137 + 2.010000 IP 10.1.4.2.49153 > 10.1.1.2.9: UDP, length 137 + 2.019068 IP 10.1.1.2.9 > 10.1.4.2.49153: UDP, length 137 + 2.020000 IP 10.1.4.2.49153 > 10.1.1.2.9: UDP, length 137 + 2.029068 IP 10.1.1.2.9 > 10.1.4.2.49153: UDP, length 137 + 2.030000 IP 10.1.4.2.49153 > 10.1.1.2.9: UDP, length 137 + 2.039068 IP 10.1.1.2.9 > 10.1.4.2.49153: UDP, length 137 + 2.040000 IP 10.1.4.2.49153 > 10.1.1.2.9: UDP, length 137 + 2.049068 IP 10.1.1.2.9 > 10.1.4.2.49153: UDP, length 137 + 2.050000 IP 10.1.4.2.49153 > 10.1.1.2.9: UDP, length 137 + 2.059068 IP 10.1.1.2.9 > 10.1.4.2.49153: UDP, length 137 + 2.060000 IP 10.1.4.2.49153 > 10.1.1.2.9: UDP, length 137 + 2.069068 IP 10.1.1.2.9 > 10.1.4.2.49153: UDP, length 137 + 2.070000 IP 10.1.4.2.49153 > 10.1.1.2.9: UDP, length 137 + 2.079068 IP 10.1.1.2.9 > 10.1.4.2.49153: UDP, length 137 + 2.080000 IP 10.1.4.2.49153 > 10.1.1.2.9: UDP, length 137 + 2.089068 IP 10.1.1.2.9 > 10.1.4.2.49153: UDP, length 137 + 2.090000 IP 10.1.4.2.49153 > 10.1.1.2.9: UDP, length 137 + 2.099068 IP 10.1.1.2.9 > 10.1.4.2.49153: UDP, length 137 + [ns-regression] ~/repos/ns-3-tutorial > +@end verbatim + +You are encouraged to think through the pcap traces and map them back to the +script. Also, take a look at the @code{star.tr} ASCII trace file (which is +quite large) to make sure you understand what it is telling you. diff --git a/doc/tutorial/conceptual-overview.texi b/doc/tutorial/conceptual-overview.texi new file mode 100644 index 000000000..10130f322 --- /dev/null +++ b/doc/tutorial/conceptual-overview.texi @@ -0,0 +1,809 @@ + +@c ======================================================================== +@c Begin document body here +@c ======================================================================== + +@c ======================================================================== +@c PART: Conceptual Overview +@c ======================================================================== +@c The below chapters are under the major heading "Getting Started" +@c This is similar to the Latex \part command +@c ======================================================================== +@c Some Conceptual Overview +@c ======================================================================== +@node Conceptual Overveiw +@chapter Conceptual Overview + +@menu +* Key Abstractions:: +@end menu + +The first thing we need to do before actually starting to look at or write +ns-3 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. + +@node Key Abstractions +@section Key Abstractions + +In this section, we'll review some terms that are commonly used in +networking, but have a specific meaning in 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 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 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 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 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,'' ns-3 applications run on +ns-3 @code{Node}s to drive simulations in the simulated world. + +@cindex Application!class +In 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 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 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 +@cindex helper +@cindex topology +@cindex helper|topology +In a real network, you will find host computers with added (or built-in) +NICs. In 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 @code{NetDevice}s to @code{Node}s, @code{NetDevice}s +to @code{Channel}s, assigning IP addresses, etc., are such common tasks +in ns-3 we provide what we call @emph{topology helpers} to make this as easy +as possible. For example, will take several distinct ns-3 core operations +to create a NetDevice, add a MAC address, connect the net device to a +@code{Node}, configure the protocol stack, and then connect the +@code{NetDevice} to a @code{Channel}. More higher level operations would be +required to connect multiple devices onto multipoint channels and then to +connect networks together into internetworks. We use topology helper objects +to compose those distinct operations into an easy to use model. + +@c ======================================================================== +@c A First ns-3 script +@c ======================================================================== +@node A First ns-3 Script +@chapter A First ns-3 script +@cindex first script +If you downloaded the system as was suggested above, you will have a release +of ns-3 in a directory called @code{repos} under your home directory. Change +into that release directory, and you should find a directory structure +something like the following: + +@verbatim + AUTHORS examples/ README samples/ tutorial/ waf* + build/ LICENSE regression/ scratch/ utils/ waf.bat* + doc/ ns3/ RELEASE_NOTES src/ VERSION wscript +@end verbatim + +@cindex first.cc +Change into the examples directory. You should see a file named +@code{first.cc} located there. This is a script that will create a simple +point-to-point link between two nodes and echo a single packet between the +nodes. Let's take a look at the script line by line. + +The first line in the file is an emacs mode line. This tells emacs about the +formatting conventions (coding style) we use in our source code. + +@verbatim + /* -*- Mode:C++; c-file-style:''gnu''; indent-tabs-mode:nil; -*- */ +@end verbatim + +This is always a somewhat controversial subject, so we might as well get it +out of the way immediately. The ns-3 project, like most large projects, has +adopted a coding style to which all contributed code must adhere. If you want +to contribute your code to the project, you will eventually have to conform to +the ns-3 coding style as described in INSERT LINK TO CODING STYLE PAGE ON WEB. +The emacs mode line above makes it easier to get the formatting correct if you +use the emacs editor. + +The ns-3 simulator is licentsed using the GNU General Public License. You +will see the appropriate GNU legalese at the head of every file in the ns-3 +distribution. + +@verbatim + /* + * 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 + */ +@end verbatim + +@section Module Includes +The code proper starts with a number of include statements. To help our high +level users deal with the large number of include files present in the system, +we group includes according to relatively large modules. We provide a single +include file that, in turn, includes all of the include files used in each +module. Rather than having to look up exactly what header you need, and +possibly have to get dependencies right, we give you the ability to load a +group of files at a large granularity. This is not the most efficient approach +but it certainly makes writing scripts much easier. Each of the ns-3 files +is placed in a directory called @code{ns3} to help with include file name +collisions. + +@verbatim + #include "ns3/core-module.h" + #include "ns3/simulator-module.h" + #include "ns3/node-module.h" + #include "ns3/helper-module.h" +@end verbatim + +The @code{ns3/core-module.h} file corresponds to the ns-3 module you will find +in the directory @code{src/core} in your downloaded release distribution. If +you list this directory you will find a large number of header files. When +you do a build, Waf will place public header files in an @code{ns3} directory +under the appropriate @code{build/debug} or @code{build/optimized} directory +depending on your configuration. Waf will also automatically generate a module +include file to load all of the public header files. Since you are following +this tutorial perfectly, you will have done a + +@verbatim + ./waf -d debug configure +@end verbatim + +to configure the project to perform debug builds. You will also have done a, + +@verbatim + ./waf +@end verbatim + +to build the project. So if you look in the directory @code{build/debug/ns-3} +you will find the four module includes shown above. + +@section Ns3 Namespace +The next line in the @code{first.cc} script is a namespace statement: + +@verbatim + using namespace ns3; +@end verbatim + +The ns-3 project is implemented in a C++ namespace called @code{ns3}. This +groups all ns-3-related declarations in a scope outside the global namespace +which we hope will help with integration with other code. The C++ @code{using} +statement introduces the ns-3 namespace into the current (global) declarative +region. This is a fancy way of saying that after this declaration, you will +not have to type @code{ns3::} before all of the ns-3 code in order to use it. +If you are unfamiliar with namespaces, please consult almost any C++ tutorial +and compare the ns3 namespace and usage here with the std namespace and +a @code{using namespace std;} statement. + +@section Logging +The next line of the script is the following, + +@verbatim + NS_LOG_COMPONENT_DEFINE ("FirstScriptExample"); +@end verbatim + +We will use this statement as a convenient place to talk about our Doxygen +documentation system. If you look at the project web site, +@uref{http://www.nsnam.org,,ns-3 project}, you will find a link to ``Other +Documentation'' in the navigation bar. If you select this link, you will be +taken to our documentation page. You will find links to our development +@code{ns-3-dev} documentation as well as that for our latest release. If you +select the @code{HTML} link you will be taken to the Doxygen documentation for +that version. + +Along the left side, you will find a graphical representation of the structure +of the documentation. A good place to start is the @code{NS-3 Modules} +``book.'' If you expand @code{Modules} you will see a list of ns-3 module +documentation. The concept of module here ties directly into the module +include files discussed above. It turns out that the ns-3 logging subsystem +is part of the @code{core} module, so go ahead and expand that node. Now, +open the @code{Debugging} book and then select the @code{Logging} page. + +You should now be looking at the Doxygen documentation for the Logging module. +In the list of @code{#define}s you will see @code{NS_LOG_COMPONENT_DEFINE}. +It would probably be good to look for the ``Detailed Description'' of the +logging module now to get a feel for the overall operation and then look at +the specific @code{NS_LOG_COMPONENT_DEFINE} documentation. I won't duplicate +the documentation here, but to summarize, this line declares a logging +component called @code{FirstScriptExample} that allows you to enable and +disable console message logging by reference to the name. + +The next lines of the script you will find are: + +@verbatim + int + main (int argc, char *argv[]) + { +@end verbatim + +This is just the declaration of the main function of your program. Just as in +any C++ program, you need to define a main function that will be the first +function run. There is nothing at all special here. Your ns-3 script is just +a C++ program. + +The next two lines of the script are used to enable two logging components that +are built into the Echo Client and Echo Server applications: + +@verbatim + LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO); + LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO); +@end verbatim + +If you have read over the Logging component documentation you will see that +there are a number of levels of detail that you enable on each component. +These two lines of code enable debug logging at the INFO level for echo +clients and servers. This will result in the application printing out +a message as packets are sent and received. + +Now we will get directly to the business of creating a topology and running +a simulation. We will use the topology helper objects to make this job as +easy as possible. + +@section Topology Helpers +@subsection NodeContainer +The next two lines of code in our script will actually create the ns-3 objects +that will represent the computers in the simulation. + +@verbatim + NodeContainer nodes; + nodes.Create (2); +@end verbatim + +Let's find the documentation for the first object before we continue. Another +way to get into the documentation system is via the @code{Classes} tab in the +HTML pages. If you still have the Doxygen handy, just scroll up to the top +of the page and select the @code{Classes} tab. You should see a new set of +tabs appear, one of which is @code{Class List}. Under that tab you will see +a list of all of the ns-3 classes. Scroll down, looking for +@code{ns3::NodeContainer}. When you find the class, go ahead and select it to +go to the Doxygen. + +You may recall that one of our key abstractions is the @code{Node}. This +represents a computer to which we are going to add things like protocol stacks, +applications and peripheral cards. The @code{NodeContainer} topology helper +provides a convenient way to create, manage and access any @code{Node} objects +that we create in order to run a simulation. The first line just declares a +NodeContainer which we call @code{nodes}. The second line calls the +@code{Create} method on the @code{nodes} object and asks the container to +create two nodes. As described in the Doxygen, the container calls down into +the ns-3 system to create two @code{Node} objects and stores the pointers +internally. + +The nodes as they stand at this point in the script do nothing. The next step +in constructing a topology is to connect our nodes together into a network. +The simplest form of network is a single point-to-point link between two nodes +so we'll construct one here. + +@subsection PointToPointHelper +We are constructing a point to point link, and in a pattern which will become +quite familiar to you, we use a topology helper object to do the low-level +work required to put the link together. Recall that two of our key +abstractions are the @code{NetDevice} and the @code{Channel}. In the real +world, this corresponds roughly to peripheral cards and network cables. +Typically these two things are intimately tied together and one cannot expect +to interchange Ethernet devices and wireless channels, for example. Our +Topology Helpers follow this intimate coupling and therefore you will use a +single @code{PointToPointHelper} to configure and connect ns-3 +@code{PointToPointNetDevice} and @code{PointToPointChannel} objects in this +script. + +The next three lines in the @code{first.cc} script are + +@verbatim + PointToPointHelper pointToPoint; + pointToPoint.SetDeviceParameter ("DataRate", StringValue ("5Mbps")); + pointToPoint.SetChannelParameter ("Delay", StringValue ("2ms")); +@end verbatim + +The first line + +@verbatim + PointToPointHelper pointToPoint; +@end verbatim + +creates a @code{PointToPointHelper} object on the stack. + +From a high-level perspective the next line, + +@verbatim + pointToPoint.SetDeviceParameter ("DataRate", StringValue ("5Mbps")); +@end verbatim + +tells the @code{PointToPointHelper} object to use the value ``5mbps'' +(five megabits per second) as the ``DataRate'' when it creates a +@code{PointToPointNetDevice} object. + +From a more detailed perspective, the string ``DataRate'' corresponds +to what we call an @code{Attribute} of the @code{PointToPointNetDevice}. +If you look at the Doxygen for class @code{ns3::PointToPointNetDevice} and +find the documentation for the @code{GetTypeId} method, you will find a list +of @code{Attributes} defined for the device. Among these is the ``DataRate'' +attribute. Most user-visible ns-3 objects have similar lists of attributes. +We use this mechanism to easily configure simulations without recompiling +as you will see in a following section. + +Similar to the ``DataRate'' on the @code{PointToPointNetDevice} we find a +``Delay'' attribute associated with the @code{PointToPointChannel}. THe +final line, + +@verbatim + pointToPoint.SetChannelParameter ("Delay", StringValue ("2ms")); +@end verbatim + +Tells the @code{PointToPointHelper} to use the value ``2ms'' (two milliseconds) +as the value of the transmission delay of every point to point channel it +creates. + +@subsection NetDeviceContainer +At this point in the script, we have a @code{NodeContainer} that contains +two nodes. We have a @code{PointToPointHelper} that is primed and ready to +make @code{PointToPointNetDevices} and wire @code{PoiintToPointChannel} objects +between them. Just as we used the @code{NodeContainer} topology helper object +to create the @code{Node}s for our simulation, we will ask the +@code{PointToPointHelper} to do the work involved in creating, configuring and +installing our devices for us. We will need to have a list of all of the +NetDevice objects that are created, so we use a NetDeviceContainer to hold +them just as we used a NodeContainer to hold the nodes we created. The +following two lines of code, + +@verbatim + NetDeviceContainer devices; + devices = pointToPoint.Install (nodes); +@end verbatim + +will finish configuring the devices and channel. The first line declares the +device container mentioned above and the second does the heavy lifting. The +@code{Install} method of the @code{PointToPointHelper} takes a +@code{NodeContainer} as a parameter. Internally, a @code{NetDeviceContainer} +is created. For each node in the @code{NodeContainer} (there must be exactly +two for a point-to-point link) a @code{PointToPointNetDevice} is created and +saved in the device container. A @code{PointToPointChannel} is created and +the two @code{PointToPointNetDevices} are attached. When objects are created +by the @code{PointToPointHelper} the attributes previously set in the helper +are used to initialize the corresponding attributes in the created objects. + +After executing the the @code{pointToPoint.Install (nodes)} call we will have +two nodes, each with an installed point-to-point net device and a +point-to-point channel between them. Both devices will send data at five +megabits per second over the channel which has a two millisecond transmission +delay. + +@subsection InternetStackHelper +We have nodes and devices configured, but we don't have any protocol stacks +installed on our nodes. The next two lines of code take care of that. + +@verbatim + InternetStackHelper stack; + stack.Install (nodes); +@end verbatim + +The @code{InternetStackHelper} is a topology helper that is to internet stacks +what the @code{PointToPointHelper} is to point-to-point net devices. The +@code{Install} method takes a @code{NodeContainer} as a parameter. When it is +executed, it will install an Internet Stack (TCP, UDP, IP, etc.) on each of +the nodes in the node container. + +@subsection Ipv4AddressHelper +Next we need to associate the devices on our nodes with IP addresses. We +provide a topology helper to manage the allocation of IP addresses. The only +user-visible API is to set the base IP address and network mask to use when +performing the actual address allocation (which is done at a lower level in the +code). + +The next two lines of code in our example script, @code{first.cc}, + +@verbatim + Ipv4AddressHelper address; + address.SetBase ("10.1.1.0", "255.255.255.0"); +@end verbatim + +declare an address helper object and tell it that it should begin allocating IP +addresses from the network 10.1.1.0 using the mask 255.255.255.0 to define +the allocatable bits. + +The next line of code, + +@verbatim + Ipv4InterfaceContainer interfaces = address.Assign (devices); +@end verbatim + +performs the actual address assignment. In ns-3 we make the association +between an IP address and a device using an @code{Ipv4Interface} object. +Just as we sometimes need a list of net devices created by a helper for future +reference we sometimes need a list of @code{Ipv4Interface} objects. The +@code{Ipv4InterfaceContainer} provides this functionality. + +Now we have a point-to-point network made with IP addresses assigned. What +we need at this point are applications to generate traffic. + +@section Applications +Another one of the core abstractions of the ns-3 system is the +@code{Application}. In this script we use two specializations of the core +ns-3 class @code{Application} called @code{UdpEchoServerApplication} and +@code{UdpEchoClientApplication}. Just as in the previous instances of ns-3 +objects, we use helper objects to help configure and manage the underlying +objects. Here, we use @code{UdpEchoServerHelper} and +@code{UdpEchoClientHelper} objects to make our lives easier. + +@subsection UdpEchoServerHelper +The following lines of code in our example script, @code{first.cc}, are used +to set up a UDP echo server application on one of the nodes we have previously +created and connected using a point-to-point link. + +@verbatim + UdpEchoServerHelper echoServer; + echoServer.SetPort (9); + + ApplicationContainer serverApps = echoServer.Install (nodes.Get (1)); + serverApps.Start (Seconds (1.0)); + serverApps.Stop (Seconds (10.0)); +@end verbatim + +The first line of code in the above snippet declares the +@code{UdpEchoServerHelper}. As usual, this isn't the application itself, it +is an object to help us create the actual applications. The second line +that has the @code{SetPort} call, is used to tell the helper to assign the +value nine to the ``Port'' attribute when creating +@code{UdpEchoServerApplication} objects. + +Similar to many other helper objects, the @code{UdpEchoServerHelper} object +has an @code{Install} method. It is the execution of this method that actually +causes the underlying echo server application to be instantiated and attached +to a node. Interestingly, the @code{Install} method takes a +@code{NodeContainter} as a parameter just as the other @code{Install} methods +we have seen. This is actually what is passed to the method even though it +doesn't look so in this case. It will be worth a slight digression +to undersand what is going on here. + +@subsubsection Implicit Conversions +This is an example of a C++ @code{implicit conversion} at work. Many +programmers use 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}. + +C++ will try to determine a sequence of type conversions to use in order to +convert an argument in a function call to the type of a corresponding paramter +in a method declaration. The method call in this case is, + +@verbatim + ApplicationContainer serverApps = echoServer.Install (nodes.Get (1)); +@end verbatim + +If you look at the declaration of the Install method in the source (or the +Doxygen) you will see, + +@verbatim + ApplicationContainer + UdpEchoServerHelper::Install (NodeContainer c) + { + ... + } +@end verbatim + +Now, the @code{Get} method of the @code{NodeContainer} returns a smart pointer +to a node object: + +@verbatim + Ptr + NodeContainer::Get (uint32_t i) const + { + ... + } +@end verbatim + +C++ notices that it needs to convert a type @code{Ptr} into a type +@code{NodeContainer}. It turns out that @code{NodeContainer} has a +constructor that takes a @code{Ptr} as a parameter. + +@verbatim + NodeContainer::NodeContainer (Ptr node) + { + ... + } +@end verbatim + +The C++ compiler implicitly provides the @code{Ptr} returned from the +@code{NodeContainer::Get} to the above constructor for @code{NodeContainer} to +make a new @code{NodeContainer} to pass to the @code{Install} method of the +@code{UdpEchoServerHelper} object. + +Taking advantage of these implicit conversion sequences can allow you to +avoid doing a lot of typing. The result is also fairly intuitive if you +don't pay close attention to the called method signatures. If you are +one of those folks that pays close attention, it does have the downside of +sometimes being surprising when you, for example, look for the method +in @code{UdpEchoServerHelper} named @code{Install} that takes a parameter +@code{Ptr} and cannot find it. + +@subsection UdpEchoServerHelper Continued +Returning to the example script, we are looking at the following code snippet. + +@verbatim + UdpEchoServerHelper echoServer; + echoServer.SetPort (9); + + ApplicationContainer serverApps = echoServer.Install (nodes.Get (1)); + serverApps.Start (Seconds (1.0)); + serverApps.Stop (Seconds (10.0)); +@end verbatim + +We now see that @code{echoServer.Install} is going to install an +@code{UdpEchoServerApplication} on the node found at index number one of the +@code{NodeContainer} we use to manage our nodes. @code{Install} will return +a container that has all of the applications (one in this case since we passed +a @code{NodeContainer} containing one node) made by the helper. + +Applications require a time to ``start'' generating traffic and a time to +``stop.'' These times are set using @code{ApplicationContainer} methods +@code{Start} and @code{Stop}. These methods take @code{Time} parameters. +In this case, we use an explicit conversion sequence to take a c++ double +1.0 and convert it to a @code{Time} object using a @code{Seconds ()} cast. +The two lines, + +@verbatim + serverApps.Start (Seconds (1.0)); + serverApps.Stop (Seconds (10.0)); +@end verbatim + +will cause the echo server application to @code{Start} (enable itself) at one +second into the simulation and to @code{Stop} (disable itself) at ten seconds +into the simulation. By virtue of the fact that we have implicilty declared +a simulation event at ten seconds, the simulation will last at least ten +seconds. + +@subsection UdpEchoClientHelper + +The echo client application is set up in a method similar to the server. +There is an underlying @code{UdpEchoClientApplication} that is managed by an +@code{UdpEchoClientHelper}. + +@verbatim + UdpEchoClientHelper echoClient; + echoClient.SetRemote (interfaces.GetAddress (1), 9); + echoClient.SetAppAttribute ("MaxPackets", UintegerValue (1)); + echoClient.SetAppAttribute ("Interval", TimeValue (Seconds (1.))); + echoClient.SetAppAttribute ("PacketSize", UintegerValue (1024)); + + ApplicationContainer clientApps = echoClient.Install (nodes.Get (0)); + clientApps.Start (Seconds (2.0)); + clientApps.Stop (Seconds (10.0)); +@end verbatim + +For the echo client, we need to set four different attributes. The first +attribute is set using the @code{SetRemote} method. Here we refer back to +the @code{Ipv4InterfaceContainer} we created to keep track of the IP addresses +we assigned to our devices. + +@verbatim + Ipv4InterfaceContainer interfaces = address.Assign (devices); +@end verbatim + +In this case, the zeroth interface in the @code{interfaces} container +cooresponds to the IP address of the zeroth node in the @code{nodes} container. +The first interface in the @code{interfaces} container cooresponds to the IP +address of the first node in the @code{nodes} container. So, in the following +line of code, we are setting the remote address of the client to be the IP +address assigned to the node on which the server resides. We tell it to send +to port nine. + +@verbatim + echoClient.SetRemote (interfaces.GetAddress (1), 9); +@end verbatim + +The ``MaxPackets'' attribute tells the client the maximum number of packets +it can send. The ``Interval'' attribute tells the cleint how long to wait +between packets and the ``PacketSize'' attribute tells the client how large +its packets should be. In this case we are telling the client to send one +1024-byte packet. + +Just as in the case of the echo server, we tell the echo client to @code{Start} +and @code{Stop}, but here we start the client one second after the server is +enabled (at two seconds into the simulation). + +@subsection Simulator +What we need to do at this point is to actually run the simulation. This is +done using the @code{Simulator} singleton which is accessed via the global +function @code{Simulator::Run} + +@verbatim + Simulator::Run (); +@end verbatim + +When we called the methods, + +@verbatim + serverApps.Start (Seconds (1.0)); + serverApps.Stop (Seconds (10.0)); + ... + clientApps.Start (Seconds (2.0)); + clientApps.Stop (Seconds (10.0)); +@end verbatim + +we actually scheduled events in the simulator at 1.0 seconds, 2.0 seconds and +10.0 seconds. When @code{Simulator::Run} is called, it will begin looking +through the list of scheduled events and executing them. First it will run +the event at 1.0 seconds, which will enable the echo server application. Then +it will run the event scheduled for t=2.0 seconds which will start the echo +client application. The start event implementation in the echo cleint will +begin the data transfer phase of the simulation by sending a packet to the +server. + +The act of sending the packet to the server will trigger a chain of events +which will be automatically scheduled and which will perform the packet echo +according to the various timing parameters that we have set in the script. + +Eventually, since we only sent one packet, the chain of events triggered by +the single client echo request will taper off and the simulation will go +idle. Once this happens, the remaining events are the @code{Stop} events +for the server and the client. When these events are executed, there are +no further events to process and @code{Simulator::Run} returns. The simulation +is complete. + +All that remains is to clean up after ourselves. This is done by calling the +global function @code{Simulator::Destroy}. As the helper functions (or low +level ns-3 code) executed they arranged it so that hooks were inserted in the +simulator to destruct all of the objects that were created. You do not have +to keep track of all of these objects yourself --- all you have to do is to +call @code{Simulator::Destroy} and exit. The remaining lines of our first +ns-3 script, @code{first.cc}, do just that + +@verbatim + Simulator::Destroy (); + return 0; + } +@end verbatim + +@section Building Your Script +We have made it trivial to build your simple scripts. All you have to do is +to drop your script into the scratch directory and it will automatically be built. Let's try it. Copy @code{examples/first.cc} into @code{scratch}: + +@verbatim + ~/repos/ns-3-tutorial > cp examples/first.cc scratch +@end verbatim + +and then build it using waf, + +@verbatim + ~/repos/ns-3-tutorial > ./waf + Entering directory `/home/craigdo/repos/ns-3-tutorial/build' + [432/477] cxx: scratch/first.cc -> build/debug/scratch/first_2.o + [433/477] cxx: scratch/simple.cc -> build/debug/scratch/simple_3.o + [475/477] cxx_link: build/debug/scratch/first_2.o -> build/debug/scratch/first + Compilation finished successfully +~/repos/ns-3-tutorial > +@end verbatim + +You can now run the example (note that if you build your program in the scratch +directory you must run it out of the scratch direcory): + +@verbatim + ~/repos/ns-3-tutorial > ./waf --run scratch/first + Entering directory `/home/craigdo/repos/ns-3-tutorial/build' + Compilation finished successfully + Sent 1024 bytes to 10.1.1.2 + Received 1024 bytes from 10.1.1.1 + Received 1024 bytes from 10.1.1.2 + ~/repos/ns-3-tutorial > +@end verbatim + +Here you see that the build system checks to make sure that the file has been +build and then runs it. You see the logging component on the echo client +note that it has sent one 1024 byte packet to the Echo Server on 10.1.1.2. +You also see the logging component on the echo server receive the 1024 bytes +from 10.1.1.1. The echo server silently echoes the packet and you see the +echo client note that it has received its packet back from the server. diff --git a/doc/tutorial/getting-started.texi b/doc/tutorial/getting-started.texi new file mode 100644 index 000000000..17519e51c --- /dev/null +++ b/doc/tutorial/getting-started.texi @@ -0,0 +1,275 @@ + +@c ======================================================================== +@c Begin document body here +@c ======================================================================== + +@c ======================================================================== +@c PART: Getting Started +@c ======================================================================== +@c The below chapters are under the major heading "Getting Started" +@c This is similar to the Latex \part command +@c +@c ======================================================================== +@c Getting Started +@c ======================================================================== +@node Getting Started +@chapter Getting Started + +@menu +* Downloading and Compiling ns-3:: +@end menu + +@c ======================================================================== +@c Downloading and Compiling ns-3 +@c ======================================================================== + +@node Downloading and Compiling ns-3 +@section Downloading and Compiling ns-3 + +@cindex Linux +@cindex Cygwin +@cindex GNU +@cindex toolchain +From this point forward, we are going to assume that the reader is working in +Linux or a Linux emulation environment (Linux, Cygwin, etc.) and has the GNU +toolchain installed and verified. + +@cindex Mercurial +@cindex Waf +We are going to assume that you have Mercurial and Waf installed and running +on the target system as described in the Getting Started section of the +ns-3 web site: @uref{http://www.nsnam.org/getting_started.html}. + +@section Downloading +@cindex tarball +The ns-3 code is available in Mercurial repositories on the server +code.nsnam.org. You can download a tarball, but we recommend working with +Mercurial --- it will make your life easier in the long run. + +@cindex repository +If you go to the following link: @uref{http://code.nsnam.org/}, +you will see a number of repositories. Many are the private repositories of +the ns-3 development team. The repositories of interest to you will be +prefixed with ``ns-3''. The current development snapshot (unreleased) +of ns-3 may be found at: @uref{http://code.nsnam.org/ns-3-dev/}. Official +releases of ns-3 will be numbered as @code{ns-3.} with any requred +hotfixes added as minor release numbers. For example, a second hotfix to a +hypothetical release nine of ns-3 would be numbered @code{ns-3.9.2}. + +The current development snapshot (unreleased) of ns-3 may be found at: +@uref{http://code.nsnam.org/ns-3-dev/}. The developers attempt to keep this +repository in a consistent, working state but it is a development area with +unreleased code present, so you may want to consider staying with an official +release. + +Since the release numbers are going to be changing, I will stick with +the more constant ns-3-dev here in the tutorial, but you can replace the +string ns-3-dev with your choice of release (e.g., ns-3.1) in the text below. +You can find the latest version of the code either by inspection of the +repository list or by going to the ``Getting Started'' web page and looking +for the latest release identifier. + +One practice is to create a directory called @code{repos} in one's home +directory under which one can keep local Mercurial repositories. +@emph{Hint: we will assume you do this later in the tutorial.} If you adopt +that approach, you can get a copy of any of the development versions of ns-3 +by typing the following into your Linux shell (assuming you have installed +Mercurial): + +@verbatim + cd + mkdir repos + cd !$ + hg clone http://code.nanam.org/ns-3-dev +@end verbatim + +As the hg command executes, you should see something like the following, + +@verbatim + destination directory: ns-3-dev + requesting all changes + adding changesets + adding manifests + adding file changes + added 3276 changesets with 12301 changes to 1353 files + 594 files updated, 0 files merged, 0 files removed, 0 files unresolved +@end verbatim + +After the clone command completes, you should have a directory called +ns-3-dev under your @code{~/repos} directory, the contents of which should +look something like the following: + +@verbatim + AUTHORS LICENSE regression/ scratch/ utils/ waf.bat* + doc/ ns3/ RELEASE_NOTES src/ VERSION wscript + examples/ README samples/ tutorial/ waf* +@end verbatim + +You are now ready to build the ns-3 distribution. + +@section Building and Testing +@cindex Waf!build +@cindex Waf!configure +@cindex Waf!debug +@cindex Waf!compile +@cindex Waf!check +@cindex Waf!regression +We use Waf to build the ns-3 project. The first thing you will need to do is +to configure the build. For reasons that will become clear later, we are +going to work with debug builds in the tutorial. To explain to Waf that it +should do debug builds you will need to execute the following command, + +@verbatim + ./waf -d debug configure +@end verbatim + +This runs the copy of Waf in the local directory (which is provided as a +convenience for you). As the build system checks for various dependencies +you should see output that looks similar to the following, + +@verbatim + ~/repos/ns-3-dev >./waf -d debug configure + Checking for program g++ : ok /usr/bin/g++ + Checking for compiler version : ok Version 4.1.2 + 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 -O2 -DNDEBUG : ok + Checking for flags -g -DDEBUG : ok + Checking for flags -g3 -O0 -DDEBUG : ok + Checking for flags -Wall : 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 + Checking for package gtk+-2.0 >= 2.12 : not found + Checking for package goocanvas gthread-2.0 : not found + Checking for program diff : ok /usr/bin/diff + 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 ns-3 programs by simply typing, + +@verbatim + ./waf check +@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 + +@cindex tests|unit +You can run the unit tests of the ns-3 distribution by running the ``check'' +command, + +@verbatim + ./waf check +@end verbatim + +You should see a report from each unit test that executes indicating that the +test has passed. + +@verbatim + ~/repos/ns-3-dev > ./waf check + Entering directory `/home/craigdo/repos/ns-3-dev/build' + Compilation finished successfully + PASS AddressHelper + PASS Wifi + PASS DcfManager + + ... + + PASS Object + PASS Ptr + PASS Callback + ~/repos/ns-3-dev > +@end verbatim + +@cindex tests|regression +This command is typically run by @code{users} to quickly verify that an ns-3 +distribution has built correctly. + +You can also run @code{regression tests} to ensure that your distribution and +tool chain have produced binaries that generate trace files which are +compatible with reference trace files stored in a central location. To run the +regression tests you run Waf with the regression flag. + +@verbatim + ./waf --regression +@end verbatim + +Waf will verify that the current files in the ns-3 distribution are built and +will then look for trace files in the aforementioned centralized location. If +your tool chain includes Mercurial, the regression tests will be downloaded +from a repository at @code{code.nsnam.org}. If you do not have Mercurial +installed, the reference traces will be downloaded from a tarball located in +the @code{releases} section of @code{www.nsnam.org}. The particular name of +the reference trace location is built from the ns-3 version located in the +VERSION file, so don't change that string. + +Once the reference traces are downloaded to your local machine, Waf will run +a number of tests that generate trace files. The content of these trace +files are compared with the reference traces just downloaded. If they are +identical, the regression tests report a PASS status. If the regression tests +pass, you should see something like, + +@verbatim + ~/repos/ns-3-dev > ./waf --regression + Entering directory `/home/craigdo/repos/ns-3-dev/build' + Compilation finished successfully + ========== Running Regression Tests ========== + Synchronizing reference traces using Mercurial. + http://code.nsnam.org/ns-3-dev-ref-traces + Done. + PASS test-csma-broadcast + PASS test-csma-multicast + PASS test-csma-one-subnet + PASS test-csma-packet-socket + PASS test-simple-error-model + PASS test-simple-global-routing + PASS test-simple-point-to-point-olsr + PASS test-tcp-large-transfer + PASS test-udp-echo + ~/repos/ns-3-dev > +@end verbatim + +If a regression tests fails you will see a FAIL indication along with a +pointer to the offending trace file and its associated reference trace file +along with a suggestion on how to run diff in order to see what has gone awry. + +@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 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 + +If you want to run programs under another tool such as gdb or valgrind, +see this @uref{http://www.nsnam.org/wiki/index.php/User_FAQ#How_to_run_NS-3_programs_under_another_tool,,wiki entry}. + +@emph{Congratulations. You are now an ns-3 user.} diff --git a/doc/tutorial/Makefile b/doc/tutorial/in-process/Makefile similarity index 100% rename from doc/tutorial/Makefile rename to doc/tutorial/in-process/Makefile diff --git a/doc/tutorial/attributes.texi b/doc/tutorial/in-process/attributes.texi similarity index 100% rename from doc/tutorial/attributes.texi rename to doc/tutorial/in-process/attributes.texi diff --git a/doc/tutorial/figures/README b/doc/tutorial/in-process/figures/README similarity index 100% rename from doc/tutorial/figures/README rename to doc/tutorial/in-process/figures/README diff --git a/doc/tutorial/figures/dumbbell.dia b/doc/tutorial/in-process/figures/dumbbell.dia similarity index 100% rename from doc/tutorial/figures/dumbbell.dia rename to doc/tutorial/in-process/figures/dumbbell.dia diff --git a/doc/tutorial/figures/helpers.obj b/doc/tutorial/in-process/figures/helpers.obj similarity index 100% rename from doc/tutorial/figures/helpers.obj rename to doc/tutorial/in-process/figures/helpers.obj diff --git a/doc/tutorial/figures/oneobj.png b/doc/tutorial/in-process/figures/oneobj.png similarity index 100% rename from doc/tutorial/figures/oneobj.png rename to doc/tutorial/in-process/figures/oneobj.png diff --git a/doc/tutorial/figures/pp.dia b/doc/tutorial/in-process/figures/pp.dia similarity index 100% rename from doc/tutorial/figures/pp.dia rename to doc/tutorial/in-process/figures/pp.dia diff --git a/doc/tutorial/figures/star.dia b/doc/tutorial/in-process/figures/star.dia similarity index 100% rename from doc/tutorial/figures/star.dia rename to doc/tutorial/in-process/figures/star.dia diff --git a/doc/tutorial/figures/threeobj.png b/doc/tutorial/in-process/figures/threeobj.png similarity index 100% rename from doc/tutorial/figures/threeobj.png rename to doc/tutorial/in-process/figures/threeobj.png diff --git a/doc/tutorial/helpers.texi b/doc/tutorial/in-process/helpers.texi similarity index 100% rename from doc/tutorial/helpers.texi rename to doc/tutorial/in-process/helpers.texi diff --git a/doc/tutorial/introduction.texi b/doc/tutorial/in-process/introduction.texi similarity index 100% rename from doc/tutorial/introduction.texi rename to doc/tutorial/in-process/introduction.texi diff --git a/doc/tutorial/log.texi b/doc/tutorial/in-process/log.texi similarity index 100% rename from doc/tutorial/log.texi rename to doc/tutorial/in-process/log.texi diff --git a/doc/tutorial/other.texi b/doc/tutorial/in-process/other.texi similarity index 100% rename from doc/tutorial/other.texi rename to doc/tutorial/in-process/other.texi diff --git a/doc/tutorial/output.texi b/doc/tutorial/in-process/output.texi similarity index 100% rename from doc/tutorial/output.texi rename to doc/tutorial/in-process/output.texi diff --git a/doc/tutorial/statistics.texi b/doc/tutorial/in-process/statistics.texi similarity index 100% rename from doc/tutorial/statistics.texi rename to doc/tutorial/in-process/statistics.texi diff --git a/doc/tutorial/troubleshoot.texi b/doc/tutorial/in-process/troubleshoot.texi similarity index 100% rename from doc/tutorial/troubleshoot.texi rename to doc/tutorial/in-process/troubleshoot.texi diff --git a/doc/tutorial/in-process/tutorial.css b/doc/tutorial/in-process/tutorial.css new file mode 100644 index 000000000..a7586ac83 --- /dev/null +++ b/doc/tutorial/in-process/tutorial.css @@ -0,0 +1,156 @@ +body { + font-family: "Trebuchet MS", "Bitstream Vera Sans", verdana, lucida, arial, helvetica, sans-serif; + background: white; + color: black; + font-size: 11pt; +} + +h1, h2, h3, h4, h5, h6 { +# color: #990000; + color: #009999; +} + +pre { + font-size: 10pt; + background: #e0e0e0; + color: black; +} + +a:link, a:visited { + font-weight: normal; + text-decoration: none; + color: #0047b9; +} + +a:hover { + font-weight: normal; + text-decoration: underline; + color: #0047b9; +} + +img { + border: 0px; +} + +#main th { + font-size: 12pt; + background: #b0b0b0; +} + +.odd { + font-size: 12pt; + background: white; +} + +.even { + font-size: 12pt; + background: #e0e0e0; +} + +.answer { + font-size: large; + font-weight: bold; +} + +.answer p { + font-size: 12pt; + font-weight: normal; +} + +.answer ul { + font-size: 12pt; + font-weight: normal; +} + +#container { + position: absolute; + width: 100%; + height: 100%; + top: 0px; +} + +#feedback { + color: #b0b0b0; + font-size: 9pt; + font-style: italic; +} + +#header { + position: absolute; + margin: 0px; + top: 10px; + height:96px; + left: 175px; + right: 10em; + bottom: auto; + background: white; + clear: both; +} + +#middle { + position: absolute; + left: 0; + height: auto; + width: 100%; +} + +#main { + position: absolute; + top: 50px; + left: 175px; + right: 100px; + background: white; + padding: 0em 0em 0em 0em; +} + +#navbar { + position: absolute; + top: 75px; + left: 0em; + width: 146px; + padding: 0px; + margin: 0px; + font-size: 10pt; +} + +#navbar a:link, #navbar a:visited { + font-weight: normal; + text-decoration: none; + color: #0047b9; +} + +#navbar a:hover { + font-weight: normal; + text-decoration: underline; + color: #0047b9; +} + +#navbar dl { + width: 146px; + padding: 0; + margin: 0 0 10px 0px; + background: #99ffff url(images/box_bottom2.gif) no-repeat bottom left; +} + +#navbar dt { + padding: 6px 10px; + font-size: 100%; + font-weight: bold; + background: #009999; + margin: 0px; + border-bottom: 1px solid #fff; + color: white; + background: #009999 url(images/box_top2.gif) no-repeat top left; +} + +#navbar dd { + font-size: 100%; + margin: 0 0 0 0px; + padding: 6px 10px; + color: #0047b9; +} + +dd#selected { + background: #99ffff url(images/arrow.gif) no-repeat; + background-position: 4px 10px; +} diff --git a/doc/tutorial/in-process/tutorial.texi b/doc/tutorial/in-process/tutorial.texi new file mode 100644 index 000000000..d2e7a4813 --- /dev/null +++ b/doc/tutorial/in-process/tutorial.texi @@ -0,0 +1,105 @@ +\input texinfo @c -*-texinfo-*- +@c %**start of header +@setfilename ns-3.info +@settitle ns-3 tutorial +@c @setchapternewpage odd +@c %**end of header + +@ifinfo +Primary documentation for the @command{ns-3} project is available in +three forms: +@itemize @bullet +@item @uref{http://www.nsnam.org/doxygen/index.html,,ns-3 Doxygen/Manual}: Documentation of the public APIs of the simulator +@item Tutorial (this document) +@item @uref{http://www.nsnam.org/wiki/index.php,, ns-3 wiki} +@end itemize + +This document is written in GNU Texinfo and is to be maintained in +revision control on the @command{ns-3} code server. Both PDF and HTML versions +should be available on the server. Changes to +the document should be discussed on the ns-developers@@isi.edu mailing list. +@end ifinfo + +@copying + +This is an @command{ns-3} tutorial. +Primary documentation for the @command{ns-3} project is available in +three forms: +@itemize @bullet +@item @uref{http://www.nsnam.org/doxygen/index.html,,ns-3 Doxygen/Manual}: Documentation of the public APIs of the simulator +@item Tutorial (this document) +@item @uref{http://www.nsnam.org/wiki/index.php,, ns-3 wiki} +@end itemize + +This document is written in GNU Texinfo and is to be maintained in +revision control on the @command{ns-3} code server. Both PDF and HTML +versions should be available on the server. Changes to +the document should be discussed on the ns-developers@@isi.edu mailing list. + +This software is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This software is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see @uref{http://www.gnu.org/licenses/}. +@end copying + +@titlepage +@title ns-3 Tutorial +@author ns-3 project +@author feedback: ns-developers@@isi.edu +@today{} + +@c @page +@vskip 0pt plus 1filll +@insertcopying +@end titlepage + +@c So the toc is printed at the start. +@anchor{Full Table of Contents} +@contents + +@ifnottex +@node Top, Overview, Full Table of Contents +@top ns-3 Tutorial (html version) + +For a pdf version of this tutorial, +see @uref{http://www.nsnam.org/docs/tutorial.pdf}. + +@insertcopying +@end ifnottex + +@menu +* Tutorial Goals:: +Part 1: Getting Started with ns-3 +* Overview:: +* Browsing:: +* Resources:: +* Downloading and Compiling:: +* Some-Prerequisites:: +Part 2: Reading ns-3 Programs +* A-First-ns-3-Script:: +Part 3: Reconfiguring Existing ns-3 Scripts +* Logging:: +* ns-3 Attributes:: +* Tracing:: +* Statistics:: +Part 4: Creating New or Revised Topologies +* Helper Functions:: +@end menu + +@include introduction.texi +@include log.texi +@include attributes.texi +@include statistics.texi +@include helpers.texi + +@printindex cp + +@bye diff --git a/doc/tutorial/tutorial.texi b/doc/tutorial/tutorial.texi index d2e7a4813..8869fcab3 100644 --- a/doc/tutorial/tutorial.texi +++ b/doc/tutorial/tutorial.texi @@ -66,7 +66,7 @@ along with this program. If not, see @uref{http://www.gnu.org/licenses/}. @contents @ifnottex -@node Top, Overview, Full Table of Contents +@node Top, Introduction, Full Table of Contents @top ns-3 Tutorial (html version) For a pdf version of this tutorial, @@ -76,29 +76,18 @@ see @uref{http://www.nsnam.org/docs/tutorial.pdf}. @end ifnottex @menu -* Tutorial Goals:: -Part 1: Getting Started with ns-3 -* Overview:: -* Browsing:: -* Resources:: -* Downloading and Compiling:: -* Some-Prerequisites:: -Part 2: Reading ns-3 Programs -* A-First-ns-3-Script:: -Part 3: Reconfiguring Existing ns-3 Scripts -* Logging:: -* ns-3 Attributes:: -* Tracing:: -* Statistics:: -Part 4: Creating New or Revised Topologies -* Helper Functions:: +* Introduction:: +* Geting Started:: +* Conceptual Overview:: +* Tweaking Ns-3:: +* Building Topologies:: @end menu @include introduction.texi -@include log.texi -@include attributes.texi -@include statistics.texi -@include helpers.texi +@include getting-started.texi +@include conceptual-overview.texi +@include tweaking.texi +@include building-topologies.texi @printindex cp diff --git a/doc/tutorial/tweaking.texi b/doc/tutorial/tweaking.texi new file mode 100644 index 000000000..2bfb70505 --- /dev/null +++ b/doc/tutorial/tweaking.texi @@ -0,0 +1,978 @@ + +@c ======================================================================== +@c Begin document body here +@c ======================================================================== + +@c ======================================================================== +@c PART: Tweaking Ns-3 +@c ======================================================================== +@c The below chapters are under the major heading "Tweaking Ns-3" +@c This is similar to the Latex \part command +@c +@c ======================================================================== +@c Tweaking Ns-3 +@c ======================================================================== +@node Tweaking Ns-3 +@chapter Tweaking Ns-3 + +@menu +* Using the Logging Module:: +* Using Command Line Arguments:: +* Using the Tracing System:: +@end menu + +@c ======================================================================== +@c Using the Logging Module +@c ======================================================================== +@node Using the Logging Module +@section Using the Logging Module + +@cindex logging +We have already taken a brief look at the ns-3 logging module while going +over the @code{first.cc} script. We will now take a closer look and see what +kind of use-cases the logging subsystem was designed to cover. + +@section Logging Overview +Many large systems support some kind of message logging facility, and ns-3 +is not an exception. In some cases, only error messages are logged to the +``operator console'' (which is typically @code{stderr} in Unix-based systems). +In other systems, warning messages may be output as well as more detailed +informational messages. In some cases, logging facilities are used to output +debug messages which can quickly turn the output into a blur. + +Ns-3 takes the view that all of these verbosity levels are useful and se +provides a selectable, multi-level approach to message logging. Logging can +be disabled completely, enabled on a component-by-component basis, enabled +globally and has selectable verbosity levels. The ns-3 log module provides +a straightforward, relatively easy to use way to get some kinds of information +out of your simulation. + +You should understand that we do provide a general purpose mechanism --- +tracing --- to get data out of your models which should be preferred for +simulation output (see the tutorial section Using the Tracing System for +more details on our tracing system). Logging should be preferred for +debugging information, warnings, error messages, or any time you want to +easily get a quick message out of your scripts or models. + +There are currently seven levels of log messages of increasing verbosity +defined in the system. + +@itemize @bullet +@item NS_LOG_ERROR --- Log error messages; +@item NS_LOG_WARN --- Log warning messages; +@item NS_LOG_DEBUG --- Log relatively rare, ad-hoc debugging messages; +@item NS_LOG_INFO --- Log informational messages about program progress; +@item NS_LOG_FUNCTION --- Log a message describing each function called; +@item NS_LOG_LOGIC -- Log messages describing logical flow in a function; +@item NS_LOG_ALL --- Log everything. +@end itemize + +We also provide an unconditional logging level that is always displayed, +irrespective of logging levels or component selection. + +@itemize @bullet +NS_LOG_UNCOND -- Log the associated message unconditionally. +@end itemize + +Each level can be requested singly or cumulatively; and can be set using a +shell environment variable (NS_LOG) or by logging system function call. As +was seen earlier in the tutorial, the logging system has Doxygen documentation +so now would be a good time to peruse the Logging Module documentation. + +Now that you have read the documentation in great detail, we can get some +interesting information out of the @code{first.cc} example script you dropped +in the scratch directory after the script walkthrough. + +@section Enabling Logging Using the NS_LOG Environment Variable +@cindex NS_LOG +First, let's use the NS_LOG environment variable to turn on some more logging +in the @code{first.cc} script you have already built. Go ahead and run the +script just as you did previously, + +@verbatim + ~/repos/ns-3-tutorial > ./waf --run scratch/first + Entering directory `/home/craigdo/repos/ns-3-tutorial/build' + Compilation finished successfully + Sent 1024 bytes to 10.1.1.2 + Received 1024 bytes from 10.1.1.1 + Received 1024 bytes from 10.1.1.2 + ~/repos/ns-3-tutorial > +@end verbatim + +The ``Sent'' and ``Received'' messages are actually logging messages from the +@code{UdpEchoClientApplication} and @code{UdpEchoServerApplication}. We can +ask the client application, for example, to print more information by setting +its logging level via the NS_LOG environment variable. I am going to assume +from here on that are using an sh-like shell that uses the``VARIABLE=value'' +syntax. If you are using a csh-like shell, then you will have to convert to +``setenv VARIABLE value'' syntax. + +Let's ask the UDP echo client application to print a little more information. +Right now, it is responding to the following line of code in @code{first.cc}, + +@verbatim + LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO); +@end verbatim + +This line of code enables the @code{LOG_LEVEL_INFO} level of logging. When +we pass a logging level flag, we are actually enabling the given level and +all lower levels. In this case, we have enabled @code{NS_LOG_INFO}, +@code{NS_LOG_DEBUG}, @code{NS_LOG_WARN} and @code{NS_LOG_ERROR}. We can +increase the logging level and get more information without changing the +script and recompiling by setting the NS_LOG environment variable like this: + +@verbatim + ~/repos/ns-3-tutorial > export NS_LOG=UdpEchoClientApplication=level_all +@end verbatim + +This sets the environment variable @code{NS_LOG} to the string, + +@verbatim + UdpEchoClientApplication=level_all +@end verbatim + +The left hand side of the assignment is the name of the logging component we +want to set, and the right hand side is the flag we want to use. In this case, +we are going to turn on all of the debugging levels for the application. If +you run the script with NS_LOG set this way you should see the following +output: + +@verbatim + ~/repos/ns-3-tutorial > ./waf --run scratch/first + Entering directory `/home/craigdo/repos/ns-3-tutorial/build' + Compilation finished successfully + UdpEchoClientApplication:UdpEchoClient() + UdpEchoClientApplication:StartApplication() + UdpEchoClientApplication:ScheduleTransmit() + UdpEchoClientApplication:Send() + Sent 1024 bytes to 10.1.1.2 + Received 1024 bytes from 10.1.1.1 + UdpEchoClientApplication:HandleRead(0x62c640, 0x62cd70) + Received 1024 bytes from 10.1.1.2 + UdpEchoClientApplication:StopApplication() + UdpEchoClientApplication:DoDispose() + UdpEchoClientApplication:~UdpEchoClient() + ~/repos/ns-3-tutorial > +@end verbatim + +The only additional debug information provided by the application is from +the NS_LOG_FUNCTION level. You can now see a log of the function calls that +were made to the application. If you look closely you will notice a single +colon between the string @code{UdpEchoClientApplication} and the method name +where you might have expected a C++ scope operator (@code{::}). This is +intentional. The name is not actually a class name, it is a logging component +name. When there is a one-to-one correspondence between a source file and a +class, this will generally be the class name but you should understand that +it is not actually a class name, and there is a single colon to separate the +logging component name from the function name that is printed. + +It turns out that in come cases, it can be hard to determine which method +actually generates a log message. If you look in the text above, you may +wonder where the string ``@code{Received 1024 bytes from 10.1.1.1}'' comes +from. You can resolve this by ORing the @code{prefix_func} level into the +@code{NS_LOG} environment variable. Try doing the following, + +@verbatim + export 'NS_LOG=UdpEchoClientApplication=level_all|prefix_func' +@end verbatim + +Note that the single quotes are required since the vertical bar is a Unix +pipe connector. + +Now, if you run the script you will see that the logging system makes sure +that every message from the given log component is prefixed with the component +name. + +@verbatim + ~/repos/ns-3-tutorial > ./waf --run scratch/first + Entering directory `/home/craigdo/repos/ns-3-tutorial/build' + Compilation finished successfully + UdpEchoClientApplication:UdpEchoClient() + UdpEchoClientApplication:StartApplication() + UdpEchoClientApplication:ScheduleTransmit() + UdpEchoClientApplication:Send() + UdpEchoClientApplication:Send(): Sent 1024 bytes to 10.1.1.2 + Received 1024 bytes from 10.1.1.1 + UdpEchoClientApplication:HandleRead(0x62c710, 0x62ce40) + UdpEchoClientApplication:HandleRead(): Received 1024 bytes from 10.1.1.2 + UdpEchoClientApplication:StopApplication() + UdpEchoClientApplication:DoDispose() + UdpEchoClientApplication:~UdpEchoClient() + ~/repos/ns-3-tutorial > +@end verbatim + +You can now see all of the messages coming from the UDP echo client application +are identified as such. The remaining message must be coming from the UDP +echo server application. We can enable that component by entering a colon +separated list of components in the NS_LOG environment variable. + +@verbatim + export 'NS_LOG=UdpEchoClientApplication=level_all|prefix_func: + UdpEchoServerApplication=level_all|prefix_func' +@end verbatim + +Note that you will need to remove the newline after the @code{:} in the +example text above. + +Now, if you run the script you will see all of the log messages from both the +echo client and server applications. You may see that this can be very useful +in debugging problems. + +@verbatim + ~/repos/ns-3-tutorial > ./waf --run scratch/first + Entering directory `/home/craigdo/repos/ns-3-tutorial/build' + Compilation finished successfully + UdpEchoServerApplication:UdpEchoServer() + UdpEchoClientApplication:UdpEchoClient() + UdpEchoServerApplication:StartApplication() + UdpEchoClientApplication:StartApplication() + UdpEchoClientApplication:ScheduleTransmit() + UdpEchoClientApplication:Send() + UdpEchoClientApplication:Send(): Sent 1024 bytes to 10.1.1.2 + UdpEchoServerApplication:HandleRead(): Received 1024 bytes from 10.1.1.1 + UdpEchoServerApplication:HandleRead(): Echoing packet + UdpEchoClientApplication:HandleRead(0x62c760, 0x62ce90) + UdpEchoClientApplication:HandleRead(): Received 1024 bytes from 10.1.1.2 + UdpEchoServerApplication:StopApplication() + UdpEchoClientApplication:StopApplication() + UdpEchoClientApplication:DoDispose() + UdpEchoServerApplication:DoDispose() + UdpEchoClientApplication:~UdpEchoClient() + UdpEchoServerApplication:~UdpEchoServer() + ~/repos/ns-3-tutorial > +@end verbatim + +It is also sometimes useful to be able to see the simulation time at which a +log message is generated. You can do this by ORing in the prefix_time bit. + +@verbatim + export 'NS_LOG=UdpEchoClientApplication=level_all|prefix_func|prefix_time: + UdpEchoServerApplication=level_all|prefix_func|prefix_time' +@end verbatim + +If you run the script now, you should see the following output: + +@verbatim + ~/repos/ns-3-tutorial > ./waf --run scratch/first + Entering directory `/home/craigdo/repos/ns-3-tutorial/build' + Compilation finished successfully + 0ns UdpEchoServerApplication:UdpEchoServer() + 0ns UdpEchoClientApplication:UdpEchoClient() + 1000000000ns UdpEchoServerApplication:StartApplication() + 2000000000ns UdpEchoClientApplication:StartApplication() + 2000000000ns UdpEchoClientApplication:ScheduleTransmit() + 2000000000ns UdpEchoClientApplication:Send() + 2000000000ns UdpEchoClientApplication:Send(): Sent 1024 bytes to 10.1.1.2 + 2003686400ns UdpEchoServerApplication:HandleRead(): Received 1024 bytes + from 10.1.1.1 + 2003686400ns UdpEchoServerApplication:HandleRead(): Echoing packet + 2007372800ns UdpEchoClientApplication:HandleRead(0x62c8c0, 0x62d020) + 2007372800ns UdpEchoClientApplication:HandleRead(): Received 1024 bytes + from 10.1.1.2 + 10000000000ns UdpEchoServerApplication:StopApplication() + 10000000000ns UdpEchoClientApplication:StopApplication() + UdpEchoClientApplication:DoDispose() + UdpEchoServerApplication:DoDispose() + UdpEchoClientApplication:~UdpEchoClient() + UdpEchoServerApplication:~UdpEchoServer() + ~/repos/ns-3-tutorial > +@end verbatim + +You can see that the constructor for the UdpEchoServer was called at a +simulation time of 0 nanoseconds. This is actually happening before the +simulation starts. The same for the UdpEchoClient constructor. + +Recall that the @code{first.cc} script started the echo server application at +one second into the simulation. You can now see that the +@code{StartApplication} of the server is, in fact, called at one second (or +one billion nanoseconds). You can also see that the echo client application +is started at a simulation time of two seconds as we requested in the script. + +You can now follow the progress of the simulation from the +@code{ScheduleTransmit} call in the client that calls @code{Send} to the +@code{HandleRead} callback in the echo server application. Note that the +elapsed time as the packet is sent across the point-to-point link is 3.6864 +milliseconds. You see the echo server logging a message telling you that it +has echoed the packet and then, after a delay, you see the echo client receive +the echoed packet. + +There is a lot that is happening under the covers in this simulation that you +are not seeing as well. You can very easily follow the entire process by +turning on all of the logging components in the system. Try setting the +@code{NS_LOG} variable to the following, + +@verbatim + export 'NS_LOG=*=level_all|prefix_func|prefix_time' +@end verbatim + +The asterisk is the logging component wildcard. This will turn on all of the +logging in all of the components in the system. I won't reproduce the output +here (as of this writing it produces 772 lines of output for the single packet +echo) but you can redirect this information into a file and look through it +with your favorite editor if you like, + +@verbatim + ~/repos/ns-3-tutorial > ./waf --run scratch/first >& log.out +@end verbatim + +I personally use this quite a bit when I am presented with a problem and I +have no idea where things are going wrong. I can follow the progress of the +code quite easily without having to set breakpoints and step through code +in a debugger. When I have a general idea about what is going wrong, I +transition into a debugger for fine-grained examination of the problem. This +output can be especially useful when your script does something completely +unexpected. + +@section Adding Logging to your Code +@cindex NS_LOG +You can add new logging to your simulations by making calls to the log +component via several macros. Let's do so in the @code{first.cc} script we +have in the @code{scratch} directory. + +Recall that we have defined a logging component in that script. + +@verbatim + NS_LOG_COMPONENT_DEFINE ("FirstScriptExample"); +@end verbatim + +You now know that you can enable all of the logging for this component by +setting the @code{NS_LOG} environment variable to the various levels. Let's +add some logging. The macro to add an informational level log message is +@code{NS_LOG_INFO}. Add one just before we start creating the nodes that +tells you that the script is ``Creating Topology.'' This is done as in this +code snippet, + +@verbatim + NS_LOG_INFO ("Creating Topology"); +@end verbatim + +Now build the script using waf and clear the @code{NS_LOG} variable to turn +off the torrent of logging we previously enabled: + +@verbatim + ~/repos/ns-3-tutorial > export NS_LOG= +@end verbatim + +Now, if you run the script, you will not see your new message since its +associated logging component has not been enabled. In order to see your +message you will have to enable the @code{FirstScriptExample} logging +component with a level greater than or equal to @code{NS_LOG_INFO}. If +you just want to see this particular level of logging, you can enable that +by, + +@verbatim + ~/repos/ns-3-tutorial > export NS_LOG=FirstScriptExample=info +@end verbatim + +If you now run the script you will see your new logging message, + +@verbatim + ~/repos/ns-3-tutorial > ./waf --run scratch/first + Entering directory `/home/craigdo/repos/ns-3-tutorial/build' + Compilation finished successfully + Creating Topology + Sent 1024 bytes to 10.1.1.2 + Received 1024 bytes from 10.1.1.1 + Received 1024 bytes from 10.1.1.2 + ~/repos/ns-3-tutorial > +@end verbatim + +As previously described, this does not also enable the lower levels of logging +but selects out the single infomational level. + +As we outlined in the Logging Overview, there are currently seven levels of +logging verbosity you can use and you can also prefix your various log messages +with component name and simulation time. + +@c ======================================================================== +@c Using Command Line Arguments +@c ======================================================================== +@node Using Command Line Arguments +@section Using Command Line Arguments + +@section Overriding Default Attributes +@cindex arguments|command line +Another way you can change the way that ns-3 scripts behave without editing +and building scripts is via @emph{command line arguments.} We provide a +mechanism to parse command line arguments and automatically set local and +global variables based on those arguments. + +The first step in using the command line argument system is to declare the +command line parser. This is done quite simply (in your main program) as +in the following code, + +@verbatim + int + main (int argc, char *argv[]) + { + ... + + CommandLine cmd; + cmd.Parse (argc, argv); + + ... + } +@end verbatim + +This simple two line snippet is actually very useful by itself. It opens the +door to the ns-3 global variable and attribute systems. Go ahead and add that +two lines of code to the @code{first.cc} script at the start of @code{main}. +Go ahead and build the script and run it, but ask the script for help in the +following way, + +@verbatim + ~/repos/ns-3-tutorial > ./waf --run "scratch/first --PrintHelp" +@end verbatim + +This will ask way to run the @code{scratch/first} script and pass the command +line argument @code{--PrintHelp} to the script. The command line parser will +now see the @code{PrintHelp} argument and respond with, + +@verbatim + ~/repos/ns-3-tutorial > ./waf --run ``scratch/first --PrintHelp'' + Entering directory `/home/craigdo/repos/ns-3-tutorial/build' + Compilation finished successfully + --PrintHelp: Print this help message. + --PrintGroups: Print the list of groups. + --PrintTypeIds: Print all TypeIds. + --PrintGroup=[group]: Print all TypeIds of group. + --PrintAttributes=[typeid]: Print all attributes of typeid. + --PrintGlobals: Print the list of globals. + ~/repos/ns-3-tutorial > +@end verbatim + +Let's focus on the @code{--PrintAttributes} option. We have already hinted +at the attribute system while walking through the @code{first.cc} script. We +looked at the following lines of code, + +@verbatim + PointToPointHelper pointToPoint; + pointToPoint.SetDeviceParameter ("DataRate", StringValue ("5Mbps")); + pointToPoint.SetChannelParameter ("Delay", StringValue ("2ms")); +@end verbatim + +and mentioned that @code{DataRate} was actually an @code{Attribute} of the +@code{PointToPointNetDevice}. Let's use the command line argument parser +to take a look at the attributes of the PointToPointNetDevice. The help +listing says that we should provide a typeid. This corresponds to the class +name of the class to which the attributes belong. In this case it will be +@code{ns3::PointToPointNetDevice}. Let's go ahead and type in, + +@verbatim + ./waf --run "scratch/first --PrintAttributes=ns3::PointToPointNetDevice" +@end verbatim + +The system will print out all of the attributes of this kind of net device. +Among the attributes you will see listed is, + +@verbatim + --ns3::PointToPointNetDevice::DataRate=[32768bps]: + The default data rate fo r point to point links +@end verbatim + +This is the default value that will be used when a PointToPointNetDevice is +created in the system. We overrode this default with the parameter setting +in the PointToPointHelper above. Let's use the default values for the +PointToPoint devices and channels by deleting the SetDeviceParameter call and +the SetChannelParameter call from the @code{first.cc} we have in the scratch +directory. + +Your script should now just declare the PointToPointHelper and not do any +sets as in the following example, + +@verbatim + ... + + NodeContainer nodes; + nodes.Create (2); + + PointToPointHelper pointToPoint; + + NetDeviceContainer devices; + devices = pointToPoint.Install (nodes); + + ... +@end verbatim + +Go ahead and build the new script with waf. Now let's go back and enable some +logging from the UDP echo server application and turn on the time prefix. + +@verbatim + export 'NS_LOG=UdpEchoServerApplication=level_all|prefix_time' +@end verbatim + +If you run the script, you should now see the following output, + +@verbatim + ~/repos/ns-3-tutorial > ./waf --run scratch/first + Entering directory `/home/craigdo/repos/ns-3-tutorial/build' + Compilation finished successfully + 0ns UdpEchoServerApplication:UdpEchoServer() + 1000000000ns UdpEchoServerApplication:StartApplication() + Sent 1024 bytes to 10.1.1.2 + 2257324218ns Received 1024 bytes from 10.1.1.1 + 2257324218ns Echoing packet + Received 1024 bytes from 10.1.1.2 + 10000000000ns UdpEchoServerApplication:StopApplication() + UdpEchoServerApplication:DoDispose() + UdpEchoServerApplication:~UdpEchoServer() + ~/repos/ns-3-tutorial > +@end verbatim + +Recall that the last time we looked at the simulation time at which the packet +was received by the echo server, it was at 2.0036864 seconds. Now it is +receiving the packet at about 2.257 seconds. This is because we just dropped +the data rate of the @code{PointToPointNetDevice} down to its default of +32768 bits per second from five megabits per second. + +If we were to provide a new @code{DataRate} using the command line, we could +speed our simulation up again, + +@verbatim + ./waf --run "scratch/first --ns3::PointToPointNetDevice::DataRate=5Mbps" +@end verbatim + +This will set the default value of the @code{DataRate} attribute back to +five megabits per second. To get the old behavior back, we will have to set +the speed-of-light delay of the channel. We can ask the command line system +to print out the @code{Attributes} of the channel just like we did the net +device: + +@verbatim + ./waf --run "scratch/first --PrintAttributes=ns3::PointToPointChannel" +@end verbatim + +and we discover the @code{Delay} attribute. + +@verbatim + --ns3::PointToPointChannel::Delay=[0ns]: + Transmission delay through the channel +@end verbatim + +We can then set both of these default values through the command line system, + +@verbatim + ./waf --run "scratch/first + --ns3::PointToPointNetDevice::DataRate=5Mbps + --ns3::PointToPointChannel::Delay=2ms" +@end verbatim + +In which case we recover the timing we had when we explicitly set the +@code{DataRate} and @code{Delay} in the script: + +@verbatim + Compilation finished successfully + 0ns UdpEchoServerApplication:UdpEchoServer() + 1000000000ns UdpEchoServerApplication:StartApplication() + Sent 1024 bytes to 10.1.1.2 + 2003686400ns Received 1024 bytes from 10.1.1.1 + 2003686400ns Echoing packet + Received 1024 bytes from 10.1.1.2 + 10000000000ns UdpEchoServerApplication:StopApplication() + UdpEchoServerApplication:DoDispose() + UdpEchoServerApplication:~UdpEchoServer() +@end verbatim + +Note that the packet is received by the server at 2.0036864 seconds. We +could actually set any of the attributes used in the script in this way. In +particular we could set the @code{UdpEchoClient} attribute @code{MaxPackets} +to some other value than one. + +How would you go about that? Give it a try. Remember you have to comment +out the place we override the default attribute in the script. Then you +have to rebuild the script using the default. You will also have to find the +syntax for actually setting the new default atribute value using the command +line help facility. Once you have this figured out you should be able to +control the number of packets echoed from the command line. Since we're nice +folks, we'll tell you that your command line should end up looking something +like, + +@verbatim + ./waf --run "scratch/first + --ns3::PointToPointNetDevice::DataRate=5Mbps + --ns3::PointToPointChannel::Delay=2ms + --ns3::UdpEchoClient::MaxPackets=2" +@end verbatim + +@subsection Hooking Your Own Values +You can also add your own hooks to the command line system. This is done +quite simply by using the @code{AddValue} method to the command line parser. + +Let's use this facility to specify the number of packets to echo in a +completely different way. Let's add a local variable called @code{nPackets} +to the main function. We'll initialize it to one to match our previous +default behavior. To allow the command line parser to change this value, we +need to hook the value into the parser. Do this by adding a call to +@code{AddValue}. Go ahead and change the @code{scratch/first.cc} script to +start with the following code, + +@verbatim + int + main (int argc, char *argv[]) + { + uint32_t nPackets = 1; + + CommandLine cmd; + cmd.AddValue("nPackets", "Number of packets to echo", nPackets); + cmd.Parse (argc, argv); + + ... +@end verbatim + +Scroll down to the point in the script where we set the @code{MaxPackets} +attribute and change it so that it is set to the variable @code{nPackets} +instead of the constant @code{1} as below. + +@verbatim + echoClient.SetAppAttribute ("MaxPackets", UintegerValue (nPackets)); +@end verbatim + +Now if you run the script and provide the @code{--PrintHelp} argument, you +should see your new @code{User Argument} listed in the help. + +@verbatim + ~/repos/ns-3-tutorial > ./waf --run "scratch/first --PrintHelp" + Entering directory `/home/craigdo/repos/ns-3-tutorial/build' + Compilation finished successfully + --PrintHelp: Print this help message. + --PrintGroups: Print the list of groups. + --PrintTypeIds: Print all TypeIds. + --PrintGroup=[group]: Print all TypeIds of group. + --PrintAttributes=[typeid]: Print all attributes of typeid. + --PrintGlobals: Print the list of globals. + User Arguments: + --nPackets: Number of packets to echo + ~/repos/ns-3-tutorial > +@end verbatim + +If you want to specify the number of packets to echo, you can now do so by +setting the @code{nPackets} argument, + +@verbatim + ~/repos/ns-3-tutorial > ./waf --run "scratch/first --nPackets=2" + Entering directory `/home/craigdo/repos/ns-3-tutorial/build' + Compilation finished successfully + Sent 1024 bytes to 10.1.1.2 + Received 1024 bytes from 10.1.1.1 + Received 1024 bytes from 10.1.1.2 + Sent 1024 bytes to 10.1.1.2 + Received 1024 bytes from 10.1.1.1 + Received 1024 bytes from 10.1.1.2 + ~/repos/ns-3-tutorial > +@end verbatim + +If you are an ns-3 user, you can use the command line argument system to +control global values and attributes. If you are a model author, you can +add new attributes to your Objects and they will automatically be available +for setting by your users through the command line system. If you are a +script author, you can add new variables to your scripts and hook them into +the command line system quite painlessly. + +@c ======================================================================== +@c Using the Tracing System +@c ======================================================================== +@node Using the Tracing System +@section Using the Tracing System + +The whole point of simulation is to generate output for further study, and +the @command{ns-3} tracing system is a primary mechanism for this. Since +@command{ns-3} is a C++ program, standard facilities for generating output +from C++ programs apply: + +@verbatim + #include + ... + int main () + { + ... + std::cout << "The value of x is " << x << std::endl; + ... + } +@end verbatim + +The basic goals of the @command{ns-3} tracing system are: + +@itemize @bullet +@item For basic tasks, the tracing system should allow the user to generate +standard tracing for popular tracing sources, and to customize which objects +generate the tracing; +@item Intermediate users must be able to extend the tracing system to modify +the output format generated, or to insert new tracing sources, without +modifying the core of the simulator; +@item Advanced users can modify the simulator core to add new tracing sources +and sinks. +@end itemize + +The @command{ns-3} tracing system is built on the concepts of independent +tracing sources and tracing sinks and a uniform mechanism for connecting +sources to sinks. Trace sources are entities that can signal events that +happen in a simulation and provide access to interesting underlying data. +For example, a trace source could indicate when a packet is received by a net +device and provide access to the packet for interested trace sinks. + +Trace sources are not useful by themselves, they must be ``connected'' to +other pieces of code that actually do something useful with the information +provided by the sink. Trace sinks are consumers of the events and data +provided by the trace sources. For example, one could create a trace sink t +hat would (when connected to the trace source of the previous example) print +out interesting parts of the received packet. + +The rationale for this explicit division is to allow users to attach new +types of sinks to existing tracing sources, without requiring editing and +recompilation of the the core of the simulator. Thus, in the example above, +a user could define a new tracing sink in her script and attach it to an +existing tracing source defined in the simulation core editing only the +user script. + +What remains to be defined is a way for users to find these hooks (tracing +sources) and attach sinks to them. A tracing namespace is defined for +this purpose. + +In this tutorial, we will walk through some pre-defined sources and sinks and +show how they may be customized with little user effort. See the ns-3 manual +or how-to sections for information on advanced tracing configuration including +extending the tracing namespace and creating new tracing sources. + +@cindex tracing +@cindex tracing|ASCII +@subsection ASCII Tracing +Ns-3 provides an ASCII trace helper that is a wrapper around low-level +tracing system. This helper lets you configure some useful and easily +understood packet traces easily. The output of a trace of a simulation run +is an ASCII file --- thus the name. For those familiar with @command{ns-2} +output, this type of trace is analogous to the @command{out.tr} generated +by many scripts. + +@cindex tracing|packets +Let's just jump right in and add some ASCII tracing output to our +@code{first.cc} script. The first thing you need to do is to add the +following code to the script just before the call to @code{Simulator::Run ()}. + +@verbatim + std::ofstream ascii; + ascii.open ("first.tr"); + PointToPointHelper::EnableAsciiAll (ascii); +@end verbatim + +The first two lines are just vanilla C++ code to open a stream that will be +written to a file named ``first.tr.'' See your favorite C++ tutorial if you +are unfamiliar with this code. The last line of code in the snippet above +tells ns-3 that you want to enable ASCII tracing on all point-to-point devices +in your simulation; and you want the (provided) trace sinks to write out +information about packet movement in ASCII format to the stream provided. +For those familiar with @command{ns-2}, the traced events are equivalent +to the popular trace points that log "+", "-", "d", and "r" events. + +Since we have used a @code{std::ofstream} object, we also need to include the +appropriate header. Add the following line to the script (I typically add it +above the ns-3 includes): + +@verbatim + #include +@end verbatim + +You can now build the script and run it from the command line: + +@verbatim + ./waf --run scratch/first +@end verbatim + +@cindex first.tr +Just as you have seen previously, you may see some messages from Waf and then +the ``Compilation finished successfully'' message. The following messages are +from the running program. When it ran, the program will have created a file +named @code{first.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 by default. If you want to control where the traces are saved +you can use the @code{--cwd} option of Waf to specify this. We have not done +so, thus we need to change into the top level directory of our repo and take a +look at the file @code{first.tr} in your favorite editor. + +@subsubsection Parsing Ascii Traces +@cindex parsing ascii traces +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}. 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 ascii trace|enqueue +@cindex ascii trace|dequeue +@cindex ascii trace|drop +@cindex ascii trace|receive +@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; +@item @code{r}: A packet was received by the net device. +@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 /NodeList/0/DeviceList/0/$ns3::PointToPointNetDevice/TxQueue/Enqueue + 03 ns3::PppHeader ( + 04 Point-to-Point Protocol: IP (0x0021)) + 05 ns3::Ipv4Header ( + 06 tos 0x0 ttl 64 id 0 offset 0 flags [none] + 07 length: 1052 10.1.1.1 > 10.1.1.2) + 08 ns3::UdpHeader ( + 09 length: 1032 49153 > 9) + 10 Payload (size=1024) +@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 again +see confirmation that this is, indeed, happening. + +@cindex node number +@cindex net device number +@cindex smart pointer +The next line of the example listing (reference 02) tell us the trace source +that originated this even expressed in the tracing namespace. You can think +of the tracing womewhat like you would a filesystem namespace. The root of +the namespace is the @code{NodeList}. This corresponds to a container in the +ns-3 code that contains all of the nodes that were created in the system. +Just as a filesystem has may have directories under the root, we have node +numbers in the @code{NodeList}. The string @code{/NodeList/0} therefore +refers to the zeroth node in the @code{NodeList} which we can think of as +``node 0.'' In each node there is a list of devices that have been installed. +This list appears next. You can see that this trace event comes from +@code{DeviceList/0} which is the zeroth device installed in the node. + +The next string, @code{$ns3::PointToPointNetDevice} tells you what kind of +device it is that is in the zeroth position of the device list for node zero. +This should by now be completely expected. Recall that the operation @code{+} +found at reference 00 means an enqueue operation on the transmit queue of the +device. This is reflected in the final segments of the ``trace path'' which +are @code{TxQueue/Enqueue}. + +The remaining lines in the trace should be fairly intuitive. References 03-04 +indicate that the packet is encapulated in the point-to-point protocol. +References 05-07 show that the packet has an IP version four header and has +originated from IP address 10.1.1.1 and is destined for 10.1.1.2. References +08-09 show that this is a UDP packet from and finally reference 10 shows that +the payload is the expected 1024 bytes. + +The next line in the trace file shows the same packet being dequeued from the +transmit queue on the same node. + +The Third line in the trace file shows the packet being received by the net +device on the node with the echo server. I have reproduced that event below. + +@verbatim + 00 r + 01 2.25732 + 02 /NodeList/1/DeviceList/0/$ns3::PointToPointNetDevice/Rx + 03 ns3::PppHeader ( + 04 Point-to-Point Protocol: IP (0x0021)) + 05 ns3::Ipv4Header ( + 06 tos 0x0 ttl 64 id 0 offset 0 flags [none] + 07 length: 1052 10.1.1.1 > 10.1.1.2) + 08 ns3::UdpHeader ( + 09 length: 1032 49153 > 9) + 10 Payload (size=1024) +@end verbatim + +Notice that the trace operation is now @code{r} and the simulation time has +increased to 2.25732 seconds. If you have been following the tutorial steps +closely this means that you have left the @code{DataRate} of the net devices +set to their default value of 32768 bps with a channel @code{Delay} of two +milliseconds. This time should be familiar as you have seen it before in a +previous section. + +The trace source namespace entry (reference 02) has changed to reflect that +this event is coming from node 1 (@code{/NodeList/1}) and the packet reception +trace source (@code{/Rx}). It should be quite easy for you to follow the +progress of the packet through the topology by looking at the rest of the +traces in the file. + +@subsection PCAP Trace Helper +@cindex pcap +@cindex Wireshark +The @command{ns-3} @emph{pcap trace helper} 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). +However, there are many traffic trace analyzers that use this packet format. +We encourage users to exploit the many tools available for analyzing pcap +traces. In this tutorial, we show how tcpdump and Wireshark can be used. + +@cindex tracing|pcap +The code used to enable pcap tracing is a one-liner. + +@verbatim + PointToPointHelper::EnablePcapAll ("first"); +@end verbatim + +Go ahead and insert this line of code after the ASCII tracing code we just +added to @code{scratch/first.cc}. Notice that we only gave the pcap trace +helper call the string, ``first,'' and not ``first.pcap'' or something +similar. This is because the parameter is a prefix, not a complete file name. +The pcap trace helper will actually create a trace file for every device in +the simulation that generates a traced event. The file names will be built +using the prefix, the node number, the device number and a ``.pcap'' suffix. + +In our example script, we will see a files named ``first-0-0.pcap'' and +``first.1-0.pcap'' which are the pcap traces for node 0, device 0 and node 1, +device 1, respectively. + +You can now run the script as you have been: + +@verbatim + ./waf --run scratch/first +@end verbatim + +If you look at the top level directory of your distribution, you should now +see three log files: @code{first.tr} is the ASCII trace file we have +previously examined. @code{first-0-0.pcap} and @code{first-1-0.pcap} +are the new pcap files we just generated. + +@subsubsection Reading output with tcpdump +@cindex tcpdump +The easiest thing to do at this point will be to use @code{tcpdump} to look +at the @code{pcap} files. Output from dumping both files is shown below: + +@verbatim + ~/repos/ns-3-tutorial > /usr/sbin/tcpdump -r first-0-0.pcap -nn -tt + reading from file first-0-0.pcap, link-type PPP (PPP) + 2.000000 IP 10.1.1.1.49153 > 10.1.1.2.9: UDP, length 1024 + 2.514648 IP 10.1.1.2.9 > 10.1.1.1.49153: UDP, length 1024 + ~/repos/ns-3-tutorial > /usr/sbin/tcpdump -r first-1-0.pcap -nn -tt + reading from file first-1-0.pcap, link-type PPP (PPP) + 2.257324 IP 10.1.1.1.49153 > 10.1.1.2.9: UDP, length 1024 + 2.257324 IP 10.1.1.2.9 > 10.1.1.1.49153: UDP, length 1024 + ~/repos/ns-3-tutorial > +@end verbatim + +You can see in the dump of ``first-0.0.pcap'' (the client device) that the +echo packet is sent at 2 seconds into the simulation. If you look at the +second dump (of ``first-1-0.pcap'') you can see that packet being received +at 2.257324 seconds. You see the packet being echoed at 2.257324 seconds +in the second dump, and finally, you see the packet being received back at +the client in the first dump at 2.514648 seconds. + +@subsubsection Reading output with Wireshark +@cindex Wireshark +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/}. + +Wireshark is a graphical user interface which can be used for displaying these +trace files. 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}. diff --git a/examples/hello-simulator.cc b/examples/hello-simulator.cc new file mode 100644 index 000000000..37f99ccd5 --- /dev/null +++ b/examples/hello-simulator.cc @@ -0,0 +1,27 @@ +/* -*- 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/core-module.h" + +NS_LOG_COMPONENT_DEFINE ("HelloSimulator"); + +using namespace ns3; + + int +main (int argc, char *argv[]) +{ + NS_LOG_UNCOND ("Hello Simulator"); +}