doc/tutorial/tweaking.texi
changeset 3332 da67e8efa347
child 3339 ff29f4ba75ed
child 3340 0b45016b6097
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/tutorial/tweaking.texi	Sat Jun 28 19:46:55 2008 -0700
@@ -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 <iostream>
+  ...
+  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 <fstream>
+@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}.