--- a/doc/tutorial/Makefile Sat Jun 28 19:39:46 2008 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-TEXI2HTML = texi2html
-TEXI2PDF = texi2dvi --pdf
-EPSTOPDF = epstopdf
-TGIF = tgif
-DIA = dia
-CONVERT = convert
-CSS = --css-include=tutorial.css
-SPLIT = --split section
-
-DIA_SOURCES = pp.dia dumbbell.dia star.dia
-TGIF_SOURCES = helpers.obj
-
-DIA_EPS = ${DIA_SOURCES:.dia=.eps}
-DIA_PNG = ${DIA_SOURCES:.dia=.png}
-DIA_PDF = ${DIA_SOURCES:.dia=.pdf}
-
-TGIF_EPS = ${TGIF_SOURCES:.obj=.eps}
-TGIF_PNG = ${TGIF_SOURCES:.obj=.png}
-TGIF_PDF = ${TGIF_SOURCES:.obj=.pdf}
-
-all: images html split-html pdf
-
-# Note: tgif requires a valid x display to convert from .obj to .png.
-# If running this makefile on a remote console, the X virtual frame
-# buffer may be needed (xorg-x11-server-Xvfb) to provide a "fake"
-# display
-images:
- cd figures/; $(DIA) -t png $(DIA_SOURCES)
- cd figures/; $(DIA) -t eps $(DIA_SOURCES)
- cd figures/; $(foreach FILE,$(DIA_EPS),$(EPSTOPDF) $(FILE);)
- cd figures/; $(TGIF) -print -png $(TGIF_SOURCES)
- cd figures/; $(TGIF) -print -eps $(TGIF_SOURCES)
- cd figures/; $(foreach FILE,$(TGIF_EPS),$(EPSTOPDF) $(FILE);)
-
-html: images
- $(TEXI2HTML) ${CSS} tutorial.texi
-
-split-html: images
- $(TEXI2HTML) ${CSS} ${SPLIT} tutorial.texi
-
-pdf: images
- $(TEXI2PDF) tutorial.texi
-
-figures-clean:
- cd figures/; rm -rf $(DIA_EPS); rm -rf $(DIA_PNG); rm -rf $(DIA_PDF)
- cd figures/; rm -rf $(TGIF_EPS); rm -rf $(TGIF_PNG); rm -rf $(TGIF_PDF)
-
-clean: figures-clean
- rm -rf tutorial.aux tutorial.cp tutorial.cps tutorial.fn tutorial.ky tutorial.pg tutorial.tp tutorial.vr tutorial.toc tutorial.log tutorial.pdf tutorial.html tutorial/
--- a/doc/tutorial/attributes.texi Sat Jun 28 19:39:46 2008 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,535 +0,0 @@
-@node ns-3 Attributes
-@chapter ns-3 Attributes
-@anchor{chap:Attributes}
-
-In ns-3 simulations, there are two main aspects to configuration:
-@itemize @bullet
-@item the simulation topology and how objects are connected
-@item the values used by the models instantiated in the topology
-@end itemize
-
-This chapter focuses on the second item above: how the many values
-in use in ns-3 are organized, documented, and modifiable by ns-3 users.
-The ns-3 attribute system is also the underpinning of how traces
-and statistics are gathered in the simulator.
-
-Before delving into details of the attribute value system,
-it will help to review some basic properties of @code{class ns3::Object}.
-
-@node Object Overview
-@section Object Overview
-
-ns-3 is fundamentally a C++ object-based system. By this we mean that
-new C++ classes (types) can be declared, defined, and subclassed
-as usual.
-
-Many ns-3 objects inherit from the @code{ns3::Object} base class. These
-objects have some additional properties that we exploit for
-organizing the system and improving the memory management
-of our objects:
-
-@itemize @bullet
-@item a "metadata" system that links the class name to a lot of
-meta-information about the object, including the base class of the subclass,
-the set of accessible constructors in the subclass, and the set of
-"attributes" of the subclass
-@item a reference counting smart pointer implementation, for memory
-management.
-@end itemize
-
-ns-3 objects that use the attribute system derive from either
-@code{ns3::Object} or @code{ns3::ObjectBase}. Most ns-3 objects
-we will discuss derive from @code{ns3::Object}, but a few that
-are outside the smart pointer memory management framework derive
-from @code{ns3::ObjectBase}.
-
-Let's review a couple of properties of these objects.
-
-@node Smart pointers
-@subsection Smart pointers
-
-As introduced above in @ref{Smart Pointers 101}, ns-3 objects
-are memory managed by a
-@uref{http://en.wikipedia.org/wiki/Smart_pointer,,reference counting smart pointer implementation}, @code{class ns3::Ptr}.
-
-Smart pointers are used extensively in the ns-3 APIs, to avoid passing
-references to heap-allocated objects that may cause memory leaks.
-For most basic usage (syntax), treat a smart pointer like a regular pointer:
-@verbatim
- Ptr<WifiNetDevice> nd = ...;
- nd->CallSomeFunction ();
- // etc.
-@end verbatim
-
-@node CreateObject
-@subsection CreateObject
-
-As we discussed above in @ref{Object Creation},
-at the lowest-level API, objects of type @code{ns3::Object} are
-not instantiated using @code{operator new} as usual but instead by
-a templated function called @code{CreateObject()}.
-
-A typical way to create such an object is as follows:
-@verbatim
- Ptr<WifiNetDevice> nd = CreateObject<WifiNetDevice> ();
-@end verbatim
-
-You can think of this as being functionally equivalent to:
-@verbatim
- WifiNetDevice* nd = new WifiNetDevice ();
-@end verbatim
-
-Objects that derive from @code{ns3::Object} must be allocated
-on the heap using CreateObject(). Those deriving from
-@code{ns3::ObjectBase}, such as ns-3 helper functions and packet
-headers and trailers, can be allocated on the stack.
-
-In some scripts, you may not see a lot of CreateObject() calls
-in the code;
-this is because there are some helper objects in effect that
-are doing the CreateObject()s for you.
-
-@node TypeId
-@subsection TypeId
-
-ns-3 classes that derive from class ns3::Object can include
-a metadata class called @code{TypeId} that records meta-information
-about the class, for use in the object aggregation and component
-manager systems:
-@itemize @bullet
- @item a unique string identifying the class
- @item the base class of the subclass, within the metadata system
- @item the set of accessible constructors in the subclass
-@end itemize
-
-@node Object Summary
-@subsection Object Summary
-
-Putting all of these concepts together, let's look at a specific
-example: @code{class ns3::Node}.
-
-The public header file node.h has a declaration that includes
-a static GetTypeId function call:
-@verbatim
-class Node : public Object
-{
-public:
- static TypeId GetTypeId (void);
- ...
-@end verbatim
-
-This is defined in the node.cc file as follows:
-@verbatim
-TypeId
-Node::GetTypeId (void)
-{
- static TypeId tid = TypeId ("ns3::Node")
- .SetParent<Object> ()
- return tid;
-}
-@end verbatim
-Finally, when users want to create Nodes, they call:
-@verbatim
- Ptr<Node> n = CreateObject<Node> n;
-@end verbatim
-
-We next discuss how attributes (values associated with member variables
-or functions of the class) are plumbed into the above TypeId.
-
-@node Attribute Overview
-@section Attribute Overview
-
-The goal of the attribute system is to organize the access of
-internal member objects of a simulation. This goal arises because,
-typically in simulation, users will cut and paste/modify existing
-simulation scripts, or will use higher-level simulation constructs,
-but often will be interested in studying or tracing particular
-internal variables. For instance, use cases such as:
-@itemize @bullet
-@item "I want to trace the packets on the wireless interface only on
-the first access point"
-@item "I want to trace the value of the TCP congestion window (every
-time it changes) on a particular TCP socket"
-@item "I want a dump of all values that were used in my simulation."
-@end itemize
-
-Similarly, users may want fine-grained access to internal
-variables in the simulation, or may want to broadly change the
-initial value used for a particular parameter in all subsequently
-created objects. Finally, users may wish to know what variables
-are settable and retrievable in a simulation configuration. This
-is not just for direct simulation interaction on the command line;
-consider also a (future) graphical user interface
-that would like to be able to provide a feature whereby a user
-might right-click on an node on the canvas and see a hierarchical,
-organized list of parameters that are settable on the node and its
-constituent member objects, and help text and default values for
-each parameter.
-
-@node Functional overview
-@subsection Functional overview
-
-We provide a way for users to access values deep in the system, without
-having to plumb accessors (pointers) through the system and walk
-pointer chains to get to them. Consider a class DropTailQueue that
-has a member variable that is an unsigned integer @code{m_maxPackets};
-this member variable controls the depth of the queue.
-
-If we look at the declaration of DropTailQueue, we see the following:
-@verbatim
-class DropTailQueue : public Queue {
-public:
- static TypeId GetTypeId (void);
- ...
-
-private:
- std::queue<Ptr<Packet> > m_packets;
- uint32_t m_maxPackets;
-};
-@end verbatim
-
-Let's consider things that a user may want to do with the value of
-m_maxPackets:
-
-@itemize @bullet
-@item Set a default value for the system, such that whenever a new
-DropTailQueue is created, this member is initialized to that default.
-@item Set or get the value on an already instantiated queue.
-@end itemize
-
-The above things typically require providing Set() and Get() functions,
-and some type of global default value.
-
-In the ns-3 attribute system, these value definitions and accessor
-functions are moved into the TypeId class; e.g.:
-@verbatim
-TypeId DropTailQueue::GetTypeId (void)
-{
- static TypeId tid = TypeId ("ns3::DropTailQueue")
- .SetParent<Queue> ()
- .AddConstructor<DropTailQueue> ()
- .AddAttribute ("MaxPackets", "The maximum number of packets accepted by this DropTailQueue.",
- Uinteger (100),
- MakeUintegerAccessor (&DropTailQueue::m_maxPackets),
- MakeUintegerChecker<uint32_t> ())
- ;
-
- return tid;
-}
-@end verbatim
-
-The AddAttribute() method is performing a number of things with this
-value:
-@itemize @bullet
-@item Binding the variable m_maxPackets to a string "MaxPackets"
-@item Providing a default value (100 packets)
-@item Providing some help text defining the value
-@item Providing a "checker" (not used in this example) that can be used to set
-bounds on the allowable range of values
-@end itemize
-
-The key point is that now the value of this variable and its default
-value are accessible in the attribute namespace, which is based on
-strings such as "MaxPackets" and TypeId strings. In the next
-section, we will provide an example script that shows how users
-may manipulate these values.
-
-@node Basic usage
-@subsection Basic usage
-
-Let's look at how a user script might access these values.
-This is based on the script found at @code{samples/main-attribute-value.cc},
-with some details stripped out.
-@verbatim
-//
-// This is a basic example of how to use the attribute system to
-// set and get a value in the underlying system; namely, an unsigned
-// integer of the maximum number of packets in a queue
-//
-
-int
-main (int argc, char *argv[])
-{
-
- // By default, the MaxPackets attribute has a value of 100 packets
- // (this default can be observed in the function DropTailQueue::GetTypeId)
- //
- // Here, we set it to 80 packets. We could use one of two value types:
- // a string-based value or a Uinteger value
- Config::SetDefault ("ns3::DropTailQueue::MaxPackets", String ("80"));
- // The below function call is redundant
- Config::SetDefault ("ns3::DropTailQueue::MaxPackets", Uinteger(80));
-
- // Allow the user to override any of the defaults and the above
- // SetDefaults() at run-time, via command-line arguments
- CommandLine cmd;
- cmd.Parse (argc, argv);
-@end verbatim
-
-The main thing to notice in the above are the two calls to
-@code{Config::SetDefault}. This is how we set the default value
-for all subsequently instantiated DropTailQueues. We illustrate
-that two types of Value classes, a String and a Uinteger class,
-can be used to assign the value to the attribute named by
-"ns3::DropTailQueue::MaxPackets".
-
-Now, we will create a few objects using the low-level API; here,
-our newly created queues will not have a m_maxPackets initialized to
-100 packets but to 80 packets, because of what we did above with
-default values.
-@verbatim
- Ptr<Node> n0 = CreateObject<Node> ();
-
- Ptr<PointToPointNetDevice> net0 = CreateObject<PointToPointNetDevice> ();
- n0->AddDevice (net0);
-
- Ptr<Queue> q = CreateObject<DropTailQueue> ();
- net0->AddQueue(q);
-@end verbatim
-
-At this point, we have created a single node (Node 0) and a
-single PointToPointNetDevice (NetDevice 0) and added a
-DropTailQueue to it.
-
-Now, we can manipulate the MaxPackets value of the already
-instantiated DropTailQueue. Here are various ways to do that.
-
-@subsubsection Pointer-based access
-
-We assume that a smart pointer (Ptr) to a relevant network device is
-in hand; here, it is the net0 pointer.
-
-One way to change the value is to access a pointer to the
-underlying queue and modify its attribute.
-
-First, we observe that we can get a pointer to the (base class)
-queue via the PointToPointNetDevice attributes, where it is called
-TxQueue
-@verbatim
- Ptr<Queue> txQueue = net0->GetAttribute ("TxQueue");
-@end verbatim
-
-Using the GetObject function, we can perform a safe downcast
-to a DropTailQueue, where MaxPackets is a member
-@verbatim
- Ptr<DropTailQueue> dtq = txQueue->GetObject <DropTailQueue> ();
- NS_ASSERT (dtq);
-@end verbatim
-
-Next, we can get the value of an attribute on this queue
-We have introduced wrapper "Value" classes for the underlying
-data types, similar to Java wrappers around these types, since
-the attribute system stores values and not disparate types.
-Here, the attribute value is assigned to a Uinteger, and
-the Get() method on this value produces the (unwrapped) uint32_t.
-@verbatim
- Uinteger limit = dtq->GetAttribute ("MaxPackets");
- NS_LOG_INFO ("1. dtq limit: " << limit.Get () << " packets");
-@end verbatim
-
-Note that the above downcast is not really needed; we could have
-done the same using the Ptr<Queue> even though the attribute
-is a member of the subclass
-@verbatim
- limit = txQueue->GetAttribute ("MaxPackets");
- NS_LOG_INFO ("2. txQueue limit: " << limit.Get () << " packets");
-@end verbatim
-
-Now, let's set it to another value (60 packets)
-@verbatim
- txQueue->SetAttribute("MaxPackets", Uinteger (60));
- limit = txQueue->GetAttribute ("MaxPackets");
- NS_LOG_INFO ("3. txQueue limit changed: " << limit.Get () << " packets");
-@end verbatim
-
-@subsubsection Namespace-based access
-
-An alternative way to get at the attribute is to use the configuration
-namespace. Here, this attribute resides on a known path in this
-namespace; this approach is useful if one doesn't have access to
-the underlying pointers and would like to configure a specific
-attribute with a single statement.
-@verbatim
- Config::Set ("/NodeList/0/DeviceList/0/TxQueue/MaxPackets", Uinteger (25));
- limit = txQueue->GetAttribute ("MaxPackets");
- NS_LOG_INFO ("4. txQueue limit changed through namespace: " <<
- limit.Get () << " packets");
-@end verbatim
-
-We could have also used wildcards to set this value for all nodes
-and all net devices (which in this simple example has the same
-effect as the previous Set())
-@verbatim
- Config::Set ("/NodeList/*/DeviceList/*/TxQueue/MaxPackets", Uinteger (15));
- limit = txQueue->GetAttribute ("MaxPackets");
- NS_LOG_INFO ("5. txQueue limit changed through wildcarded namespace: " <<
- limit.Get () << " packets");
-@end verbatim
-
-@node Setting through constructors and helper classes
-@subsection Setting through constructors helper classes
-
-Arbitrary combinations of attributes can be set and fetched from
-the helper and low-level APIs; either from the constructors themselves:
-@verbatim
-Ptr<Object> p = CreateObject<MyNewObject> ("n1", v1, "n2", v2, ...);
-@end verbatim
-or from the higher-level helper APIs, such as:
-@verbatim
- mobility.SetPositionAllocator ("GridPositionAllocator",
- "MinX", FpValue (-100.0),
- "MinY", FpValue (-100.0),
- "DeltaX", FpValue (5.0),
- "DeltaY", FpValue (20.0),
- "GridWidth", UintValue (20),
- "LayoutType", "RowFirst");
-@end verbatim
-
-@node Value classes
-@subsection Value classes
-Readers will note the new Value classes. These can be thought of as
-an intermediate class that can be used to convert from raw types to the
-Values that are used by the system. Recall that this database is holding
-objects of many types with a single generic type. Conversions to this
-type can either be done using an intermediate class (IntValue, FpValue for
-"floating point") or via strings. Direct implicit conversion of types
-to Value is not really practical. So in the above, users have a choice
-of using strings or values:
-@verbatim
-p->Set ("cwnd", "100"); // string-based setter
-p->Set ("cwnd", IntValue(100)); // value-based setter
-@end verbatim
-
-The system provides some macros that help users declare and define
-new Value subclasses for new types that they want to introduce into
-the attribute system.
-
-@node Extending attributes
-@section Extending attributes
-
-The ns-3 system will place a number of internal values under the
-attribute system, but undoubtedly users will want to extend this
-to pick up ones we have missed, or to add their own classes to this.
-
-@subsection Adding an existing internal variable to the metadata system
-
-// XXX revise me
-
-Consider this variable in class TcpSocket:
-@verbatim
- uint32_t m_cWnd; // Congestion window
-@end verbatim
-
-Suppose that someone working with Tcp wanted to get or set the
-value of that variable using the metadata system. If it were not
-already provided by ns-3, the user could declare the following addition
-in the metadata system (to the TypeId declaration for TcpSocket):
-@verbatim
- .AddParameter ("Congestion window",
- "Tcp congestion window (bytes)",
- MakeUIntParamSpec (&TcpSocket::m_cWnd, 1));
-
-@end verbatim
-
-Now, the user with a pointer to the TcpSocket can perform operations
-such as setting and getting the value, without having to add these
-functions explicitly. Furthermore, access controls can be applied, such
-as allowing the parameter to be read and not written, or bounds
-checking on the permissible values can be applied.
-
-@subsection Adding a new TypeId
-
-Here, we discuss the impact on a user who wants to add a new class to
-ns-3; what additional things must be done to hook it into this system.
-
-We've already introduced what a TypeId definition looks like:
-@verbatim
-TypeId
-RandomWalk2dMobilityModel::GetTypeId (void)
-{
- static TypeId tid = TypeId ("RandomWalkMobilityModel")
- .SetParent<MobilityModel> ()
- .SetGroupName ("Mobility")
- .AddConstructor<RandomWalk2dMobilityModel> ()
- // followed by a number of Parameters
- .AddParameter ("bounds",
- "Bounds of the area to cruise.",
- MakeRectangleParamSpec (&RandomWalk2dMobilityModel::m_bounds, Rectangle (0.0, 0.0, 100.0, 100.0)))
- .AddParameter ("time",
- "Change current direction and speed after moving for this delay.",
- MakeTimeParamSpec (&RandomWalk2dMobilityModel::m_modeTime,
- Seconds (1.0)))
-
- // etc (more parameters).
-@end verbatim
-
-The declaration for this in the class declaration is one-line public
-member method:
-@verbatim
- public:
- static TypeId GetTypeId (void);
-@end verbatim
-
-@section Adding new class type to the Value system
-
-From the perspective of the user who writes a new class in the system and
-wants to hook it in to the attribute system, there is mainly the matter
-of writing
-the conversions to/from strings and Values. Most of this can be
-copy/pasted with macro-ized code. For instance, consider class
-Rectangle in the @code{src/mobility/} directory:
-
-One line is added to the class declaration:
-@verbatim
-/**
- * \brief a 2d rectangle
- */
-class Rectangle
-{
-...
-
- VALUE_HELPER_HEADER_1 (Rectangle);
-};
-@end verbatim
-
-One templatized declaration, and two operators, are added below the
-class declaration:
-
-@verbatim
-std::ostream &operator << (std::ostream &os, const Rectangle &rectangle);
-std::istream &operator >> (std::istream &is, Rectangle &rectangle);
-
-VALUE_HELPER_HEADER_2 (Rectangle);
-@end verbatim
-
-In the class definition, the code looks like this:
-
-@verbatim
-VALUE_HELPER_CPP (Rectangle);
-
-std::ostream &
-operator << (std::ostream &os, const Rectangle &rectangle)
-{
- os << rectangle.xMin << "|" << rectangle.xMax << "|" << rectangle.yMin << "|" << rectangle.yMax;
- return os;
-}
-std::istream &
-operator >> (std::istream &is, Rectangle &rectangle)
- {
- char c1, c2, c3;
- is >> rectangle.xMin >> c1 >> rectangle.xMax >> c2 >> rectangle.yMin >> c3 >> rectangle.yMax;
- if (c1 != '|' ||
- c2 != '|' ||
- c3 != '|')
- {
- is.setstate (std::ios_base::failbit);
- }
- return is;
-}
-@end verbatim
-
-These stream operators simply convert from a string representation of the
-Rectangle ("xMin|xMax|yMin|yMax") to the underlying Rectangle, and the
-modeler must specify these operators and the string syntactical representation
-of an instance of the new class.
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/tutorial/building-topologies.texi Sat Jun 28 19:46:55 2008 -0700
@@ -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.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/tutorial/conceptual-overview.texi Sat Jun 28 19:46:55 2008 -0700
@@ -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<Node>
+ NodeContainer::Get (uint32_t i) const
+ {
+ ...
+ }
+@end verbatim
+
+C++ notices that it needs to convert a type @code{Ptr<Node>} into a type
+@code{NodeContainer}. It turns out that @code{NodeContainer} has a
+constructor that takes a @code{Ptr<Node>} as a parameter.
+
+@verbatim
+ NodeContainer::NodeContainer (Ptr<Node> node)
+ {
+ ...
+ }
+@end verbatim
+
+The C++ compiler implicitly provides the @code{Ptr<Node>} 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<Node>} 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.
--- a/doc/tutorial/figures/README Sat Jun 28 19:39:46 2008 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-Please write image files in a vector graphics format, when possible, and
-generate the .png and .pdf versions on the fly (see ../Makefile).
-
-Currently supported tools are dia and tgif. xfig could be added similarly
-if someone wants to add it. The main requirement for adding another format
-is that the tool to edit it is freely available and that a cron script can
-autogenerate the pdf and png from the figure source.
-
-Store the .dia, or .obj versions in mercurial, but not the .png or .pdfs.
-If the figure is not available in a vector graphics format, store both
-a .png and a .pdf version in this directory.
-
-If you add a source (.dia, .obj) file here, remember to add it to
-the list of figure sources in the Makefile in the directory above
-
-Note: tgif can convert from .obj to .pdf, but the pdf that results takes
-up a whole page. Instead, we convert to an intermediate .eps step, and
-then run epstopdf.
Binary file doc/tutorial/figures/dumbbell.dia has changed
--- a/doc/tutorial/figures/helpers.obj Sat Jun 28 19:39:46 2008 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,115 +0,0 @@
-%TGIF 4.1.43-QPL
-state(0,37,100.000,0,0,0,32,1,9,1,1,0,0,1,2,1,0,'Courier',0,80640,0,2,0,10,0,0,1,1,0,16,0,0,1,1,1,1,1088,1408,1,0,2880,0).
-%
-% @(#)$Header$
-% %W%
-%
-unit("1 pixel/pixel").
-color_info(11,65535,0,[
- "magenta", 65535, 0, 65535, 65535, 0, 65535, 1,
- "red", 65535, 0, 0, 65535, 0, 0, 1,
- "green", 0, 65535, 0, 0, 65535, 0, 1,
- "blue", 0, 0, 65535, 0, 0, 65535, 1,
- "yellow", 65535, 65535, 0, 65535, 65535, 0, 1,
- "pink", 65535, 49344, 52171, 65535, 49344, 52171, 1,
- "cyan", 0, 65535, 65535, 0, 65535, 65535, 1,
- "CadetBlue", 24415, 40606, 41120, 24415, 40606, 41120, 1,
- "white", 65535, 65535, 65535, 65535, 65535, 65535, 1,
- "black", 0, 0, 0, 0, 0, 0, 1,
- "DarkSlateGray", 12079, 20303, 20303, 12079, 20303, 20303, 1
-]).
-script_frac("0.6").
-fg_bg_colors('black','white').
-dont_reencode("FFDingbests:ZapfDingbats").
-page(1,"",1,'').
-text('black',272,195,2,0,1,248,36,0,13,5,0,0,0,0,2,248,36,0,0,"",0,0,0,0,208,'',[
-minilines(248,36,0,0,0,0,0,[
-mini_line(200,13,5,0,0,0,[
-str_block(0,200,13,5,0,-8,0,0,0,[
-str_seg('black','Courier',0,80640,200,13,5,0,-8,0,0,0,0,0,
- "low-level APIs (all src/ ")])
-]),
-mini_line(248,13,5,0,0,0,[
-str_block(0,248,13,5,0,-2,0,0,0,[
-str_seg('black','Courier',0,80640,248,13,5,0,-2,0,0,0,0,0,
- "directories except src/helper/)")])
-])
-])]).
-rcbox('black','',96,240,384,288,5,1,1,0,16,2,0,0,0,0,'1',0,[
-]).
-text('black',192,259,1,0,1,112,18,3,13,5,2,0,0,0,2,112,18,0,0,"",0,0,0,0,272,'',[
-minilines(112,18,0,0,0,0,0,[
-mini_line(112,13,5,0,0,0,[
-str_block(0,112,13,5,0,0,0,0,0,[
-str_seg('black','Courier',0,80640,112,13,5,0,0,0,0,0,0,0,
- "ns-3 simulator")])
-])
-])]).
-poly('black','',2,[
- 272,208,240,240],0,1,1,17,0,0,2,0,0,0,0,'1',0,0,
- "0","",[
- 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
-]).
-poly('black','',2,[
- 240,176,240,240],1,1,1,18,0,0,0,0,0,0,0,'1',0,0,
- "0","",[
- 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
-]).
-rcbox('black','',176,128,384,176,5,1,1,0,16,25,0,0,0,0,'1',0,[
-]).
-text('black',192,131,2,0,1,120,36,26,13,5,2,0,0,0,2,120,36,0,0,"",0,0,0,0,144,'',[
-minilines(120,36,0,0,0,0,0,[
-mini_line(120,13,5,0,0,0,[
-str_block(0,120,13,5,0,-1,0,0,0,[
-str_seg('black','Courier',0,80640,120,13,5,0,-1,0,0,0,0,0,
- "ns-3 helper API")])
-]),
-mini_line(96,13,5,0,0,0,[
-str_block(0,96,13,5,0,-2,0,0,0,[
-str_seg('black','Courier',0,80640,96,13,5,0,-2,0,0,0,0,0,
- "(src/helper)")])
-])
-])]).
-rcbox('black','',96,16,384,64,0,1,1,0,16,32,0,0,0,0,'1',0,[
-]).
-poly('black','',2,[
- 240,64,240,128],1,1,1,36,0,0,0,0,0,0,0,'1',0,0,
- "0","",[
- 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
-]).
-text('black',272,83,2,0,1,200,36,40,13,5,0,0,0,0,2,200,36,0,0,"",0,0,0,0,96,'',[
-minilines(200,36,0,0,0,0,0,[
-mini_line(200,13,5,0,0,0,[
-str_block(0,200,13,5,0,-2,0,0,0,[
-str_seg('black','Courier',0,80640,200,13,5,0,-2,0,0,0,0,0,
- "helper APIs (src/helper/)")])
-]),
-mini_line(192,13,5,0,0,0,[
-str_block(0,192,13,5,0,-1,0,0,0,[
-str_seg('black','Courier',0,80640,192,13,5,0,-1,0,0,0,0,0,
- "call into low-level APIs")])
-])
-])]).
-poly('black','',2,[
- 272,96,240,128],0,1,1,41,0,0,2,0,0,0,0,'1',0,0,
- "0","",[
- 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
-]).
-text('black',128,19,2,0,1,232,36,47,13,5,0,0,0,0,2,232,36,0,0,"",0,0,0,0,32,'',[
-minilines(232,36,0,0,0,0,0,[
-mini_line(224,13,5,0,0,0,[
-str_block(0,224,13,5,0,-2,0,0,0,[
-str_seg('black','Courier',0,80640,224,13,5,0,-2,0,0,0,0,0,
- "ns-3 scripts (main programs)")])
-]),
-mini_line(232,13,5,0,0,0,[
-str_block(0,232,13,5,0,-1,0,0,0,[
-str_seg('black','Courier',0,80640,232,13,5,0,-1,0,0,0,0,0,
- "- may use either or both APIs")])
-])
-])]).
-poly('black','',2,[
- 144,64,144,240],1,1,1,50,0,0,0,0,0,0,0,'1',0,0,
- "0","",[
- 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
-]).
Binary file doc/tutorial/figures/oneobj.png has changed
Binary file doc/tutorial/figures/pp.dia has changed
Binary file doc/tutorial/figures/star.dia has changed
Binary file doc/tutorial/figures/threeobj.png has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/tutorial/getting-started.texi Sat Jun 28 19:46:55 2008 -0700
@@ -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.<release>} 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.}
--- a/doc/tutorial/helpers.texi Sat Jun 28 19:39:46 2008 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-@node Helper Functions
-@chapter Helper Functions
-@anchor{chap:Helpers}
-This chapter describes an intermediate API for the simulator; what we
-call the "helper API". The helper API is implemented in
-@code{src/helper/} directory; it depends on (and wraps) the low-level
-API which is implemented everywhere else in @code{src/}. The following
-figure shows this relationship.
-@center @image{figures/helpers,,,,png}
-
-The use of the helper API is optional. It has two main goals:
-@itemize @bullet
-@item Provide "syntactic sugar" to wrap a number of related low-level
-API calls together, that would normally be grouped together often, into
-something that is more user-friendly.
-@item Handle configuration of larger topological units (e.g., a set
-of nodes or a set of nodes on a particular link) .
-@end itemize
-
-(more to follow)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/tutorial/in-process/Makefile Sat Jun 28 19:46:55 2008 -0700
@@ -0,0 +1,49 @@
+TEXI2HTML = texi2html
+TEXI2PDF = texi2dvi --pdf
+EPSTOPDF = epstopdf
+TGIF = tgif
+DIA = dia
+CONVERT = convert
+CSS = --css-include=tutorial.css
+SPLIT = --split section
+
+DIA_SOURCES = pp.dia dumbbell.dia star.dia
+TGIF_SOURCES = helpers.obj
+
+DIA_EPS = ${DIA_SOURCES:.dia=.eps}
+DIA_PNG = ${DIA_SOURCES:.dia=.png}
+DIA_PDF = ${DIA_SOURCES:.dia=.pdf}
+
+TGIF_EPS = ${TGIF_SOURCES:.obj=.eps}
+TGIF_PNG = ${TGIF_SOURCES:.obj=.png}
+TGIF_PDF = ${TGIF_SOURCES:.obj=.pdf}
+
+all: images html split-html pdf
+
+# Note: tgif requires a valid x display to convert from .obj to .png.
+# If running this makefile on a remote console, the X virtual frame
+# buffer may be needed (xorg-x11-server-Xvfb) to provide a "fake"
+# display
+images:
+ cd figures/; $(DIA) -t png $(DIA_SOURCES)
+ cd figures/; $(DIA) -t eps $(DIA_SOURCES)
+ cd figures/; $(foreach FILE,$(DIA_EPS),$(EPSTOPDF) $(FILE);)
+ cd figures/; $(TGIF) -print -png $(TGIF_SOURCES)
+ cd figures/; $(TGIF) -print -eps $(TGIF_SOURCES)
+ cd figures/; $(foreach FILE,$(TGIF_EPS),$(EPSTOPDF) $(FILE);)
+
+html: images
+ $(TEXI2HTML) ${CSS} tutorial.texi
+
+split-html: images
+ $(TEXI2HTML) ${CSS} ${SPLIT} tutorial.texi
+
+pdf: images
+ $(TEXI2PDF) tutorial.texi
+
+figures-clean:
+ cd figures/; rm -rf $(DIA_EPS); rm -rf $(DIA_PNG); rm -rf $(DIA_PDF)
+ cd figures/; rm -rf $(TGIF_EPS); rm -rf $(TGIF_PNG); rm -rf $(TGIF_PDF)
+
+clean: figures-clean
+ rm -rf tutorial.aux tutorial.cp tutorial.cps tutorial.fn tutorial.ky tutorial.pg tutorial.tp tutorial.vr tutorial.toc tutorial.log tutorial.pdf tutorial.html tutorial/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/tutorial/in-process/attributes.texi Sat Jun 28 19:46:55 2008 -0700
@@ -0,0 +1,535 @@
+@node ns-3 Attributes
+@chapter ns-3 Attributes
+@anchor{chap:Attributes}
+
+In ns-3 simulations, there are two main aspects to configuration:
+@itemize @bullet
+@item the simulation topology and how objects are connected
+@item the values used by the models instantiated in the topology
+@end itemize
+
+This chapter focuses on the second item above: how the many values
+in use in ns-3 are organized, documented, and modifiable by ns-3 users.
+The ns-3 attribute system is also the underpinning of how traces
+and statistics are gathered in the simulator.
+
+Before delving into details of the attribute value system,
+it will help to review some basic properties of @code{class ns3::Object}.
+
+@node Object Overview
+@section Object Overview
+
+ns-3 is fundamentally a C++ object-based system. By this we mean that
+new C++ classes (types) can be declared, defined, and subclassed
+as usual.
+
+Many ns-3 objects inherit from the @code{ns3::Object} base class. These
+objects have some additional properties that we exploit for
+organizing the system and improving the memory management
+of our objects:
+
+@itemize @bullet
+@item a "metadata" system that links the class name to a lot of
+meta-information about the object, including the base class of the subclass,
+the set of accessible constructors in the subclass, and the set of
+"attributes" of the subclass
+@item a reference counting smart pointer implementation, for memory
+management.
+@end itemize
+
+ns-3 objects that use the attribute system derive from either
+@code{ns3::Object} or @code{ns3::ObjectBase}. Most ns-3 objects
+we will discuss derive from @code{ns3::Object}, but a few that
+are outside the smart pointer memory management framework derive
+from @code{ns3::ObjectBase}.
+
+Let's review a couple of properties of these objects.
+
+@node Smart pointers
+@subsection Smart pointers
+
+As introduced above in @ref{Smart Pointers 101}, ns-3 objects
+are memory managed by a
+@uref{http://en.wikipedia.org/wiki/Smart_pointer,,reference counting smart pointer implementation}, @code{class ns3::Ptr}.
+
+Smart pointers are used extensively in the ns-3 APIs, to avoid passing
+references to heap-allocated objects that may cause memory leaks.
+For most basic usage (syntax), treat a smart pointer like a regular pointer:
+@verbatim
+ Ptr<WifiNetDevice> nd = ...;
+ nd->CallSomeFunction ();
+ // etc.
+@end verbatim
+
+@node CreateObject
+@subsection CreateObject
+
+As we discussed above in @ref{Object Creation},
+at the lowest-level API, objects of type @code{ns3::Object} are
+not instantiated using @code{operator new} as usual but instead by
+a templated function called @code{CreateObject()}.
+
+A typical way to create such an object is as follows:
+@verbatim
+ Ptr<WifiNetDevice> nd = CreateObject<WifiNetDevice> ();
+@end verbatim
+
+You can think of this as being functionally equivalent to:
+@verbatim
+ WifiNetDevice* nd = new WifiNetDevice ();
+@end verbatim
+
+Objects that derive from @code{ns3::Object} must be allocated
+on the heap using CreateObject(). Those deriving from
+@code{ns3::ObjectBase}, such as ns-3 helper functions and packet
+headers and trailers, can be allocated on the stack.
+
+In some scripts, you may not see a lot of CreateObject() calls
+in the code;
+this is because there are some helper objects in effect that
+are doing the CreateObject()s for you.
+
+@node TypeId
+@subsection TypeId
+
+ns-3 classes that derive from class ns3::Object can include
+a metadata class called @code{TypeId} that records meta-information
+about the class, for use in the object aggregation and component
+manager systems:
+@itemize @bullet
+ @item a unique string identifying the class
+ @item the base class of the subclass, within the metadata system
+ @item the set of accessible constructors in the subclass
+@end itemize
+
+@node Object Summary
+@subsection Object Summary
+
+Putting all of these concepts together, let's look at a specific
+example: @code{class ns3::Node}.
+
+The public header file node.h has a declaration that includes
+a static GetTypeId function call:
+@verbatim
+class Node : public Object
+{
+public:
+ static TypeId GetTypeId (void);
+ ...
+@end verbatim
+
+This is defined in the node.cc file as follows:
+@verbatim
+TypeId
+Node::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::Node")
+ .SetParent<Object> ()
+ return tid;
+}
+@end verbatim
+Finally, when users want to create Nodes, they call:
+@verbatim
+ Ptr<Node> n = CreateObject<Node> n;
+@end verbatim
+
+We next discuss how attributes (values associated with member variables
+or functions of the class) are plumbed into the above TypeId.
+
+@node Attribute Overview
+@section Attribute Overview
+
+The goal of the attribute system is to organize the access of
+internal member objects of a simulation. This goal arises because,
+typically in simulation, users will cut and paste/modify existing
+simulation scripts, or will use higher-level simulation constructs,
+but often will be interested in studying or tracing particular
+internal variables. For instance, use cases such as:
+@itemize @bullet
+@item "I want to trace the packets on the wireless interface only on
+the first access point"
+@item "I want to trace the value of the TCP congestion window (every
+time it changes) on a particular TCP socket"
+@item "I want a dump of all values that were used in my simulation."
+@end itemize
+
+Similarly, users may want fine-grained access to internal
+variables in the simulation, or may want to broadly change the
+initial value used for a particular parameter in all subsequently
+created objects. Finally, users may wish to know what variables
+are settable and retrievable in a simulation configuration. This
+is not just for direct simulation interaction on the command line;
+consider also a (future) graphical user interface
+that would like to be able to provide a feature whereby a user
+might right-click on an node on the canvas and see a hierarchical,
+organized list of parameters that are settable on the node and its
+constituent member objects, and help text and default values for
+each parameter.
+
+@node Functional overview
+@subsection Functional overview
+
+We provide a way for users to access values deep in the system, without
+having to plumb accessors (pointers) through the system and walk
+pointer chains to get to them. Consider a class DropTailQueue that
+has a member variable that is an unsigned integer @code{m_maxPackets};
+this member variable controls the depth of the queue.
+
+If we look at the declaration of DropTailQueue, we see the following:
+@verbatim
+class DropTailQueue : public Queue {
+public:
+ static TypeId GetTypeId (void);
+ ...
+
+private:
+ std::queue<Ptr<Packet> > m_packets;
+ uint32_t m_maxPackets;
+};
+@end verbatim
+
+Let's consider things that a user may want to do with the value of
+m_maxPackets:
+
+@itemize @bullet
+@item Set a default value for the system, such that whenever a new
+DropTailQueue is created, this member is initialized to that default.
+@item Set or get the value on an already instantiated queue.
+@end itemize
+
+The above things typically require providing Set() and Get() functions,
+and some type of global default value.
+
+In the ns-3 attribute system, these value definitions and accessor
+functions are moved into the TypeId class; e.g.:
+@verbatim
+TypeId DropTailQueue::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::DropTailQueue")
+ .SetParent<Queue> ()
+ .AddConstructor<DropTailQueue> ()
+ .AddAttribute ("MaxPackets", "The maximum number of packets accepted by this DropTailQueue.",
+ Uinteger (100),
+ MakeUintegerAccessor (&DropTailQueue::m_maxPackets),
+ MakeUintegerChecker<uint32_t> ())
+ ;
+
+ return tid;
+}
+@end verbatim
+
+The AddAttribute() method is performing a number of things with this
+value:
+@itemize @bullet
+@item Binding the variable m_maxPackets to a string "MaxPackets"
+@item Providing a default value (100 packets)
+@item Providing some help text defining the value
+@item Providing a "checker" (not used in this example) that can be used to set
+bounds on the allowable range of values
+@end itemize
+
+The key point is that now the value of this variable and its default
+value are accessible in the attribute namespace, which is based on
+strings such as "MaxPackets" and TypeId strings. In the next
+section, we will provide an example script that shows how users
+may manipulate these values.
+
+@node Basic usage
+@subsection Basic usage
+
+Let's look at how a user script might access these values.
+This is based on the script found at @code{samples/main-attribute-value.cc},
+with some details stripped out.
+@verbatim
+//
+// This is a basic example of how to use the attribute system to
+// set and get a value in the underlying system; namely, an unsigned
+// integer of the maximum number of packets in a queue
+//
+
+int
+main (int argc, char *argv[])
+{
+
+ // By default, the MaxPackets attribute has a value of 100 packets
+ // (this default can be observed in the function DropTailQueue::GetTypeId)
+ //
+ // Here, we set it to 80 packets. We could use one of two value types:
+ // a string-based value or a Uinteger value
+ Config::SetDefault ("ns3::DropTailQueue::MaxPackets", String ("80"));
+ // The below function call is redundant
+ Config::SetDefault ("ns3::DropTailQueue::MaxPackets", Uinteger(80));
+
+ // Allow the user to override any of the defaults and the above
+ // SetDefaults() at run-time, via command-line arguments
+ CommandLine cmd;
+ cmd.Parse (argc, argv);
+@end verbatim
+
+The main thing to notice in the above are the two calls to
+@code{Config::SetDefault}. This is how we set the default value
+for all subsequently instantiated DropTailQueues. We illustrate
+that two types of Value classes, a String and a Uinteger class,
+can be used to assign the value to the attribute named by
+"ns3::DropTailQueue::MaxPackets".
+
+Now, we will create a few objects using the low-level API; here,
+our newly created queues will not have a m_maxPackets initialized to
+100 packets but to 80 packets, because of what we did above with
+default values.
+@verbatim
+ Ptr<Node> n0 = CreateObject<Node> ();
+
+ Ptr<PointToPointNetDevice> net0 = CreateObject<PointToPointNetDevice> ();
+ n0->AddDevice (net0);
+
+ Ptr<Queue> q = CreateObject<DropTailQueue> ();
+ net0->AddQueue(q);
+@end verbatim
+
+At this point, we have created a single node (Node 0) and a
+single PointToPointNetDevice (NetDevice 0) and added a
+DropTailQueue to it.
+
+Now, we can manipulate the MaxPackets value of the already
+instantiated DropTailQueue. Here are various ways to do that.
+
+@subsubsection Pointer-based access
+
+We assume that a smart pointer (Ptr) to a relevant network device is
+in hand; here, it is the net0 pointer.
+
+One way to change the value is to access a pointer to the
+underlying queue and modify its attribute.
+
+First, we observe that we can get a pointer to the (base class)
+queue via the PointToPointNetDevice attributes, where it is called
+TxQueue
+@verbatim
+ Ptr<Queue> txQueue = net0->GetAttribute ("TxQueue");
+@end verbatim
+
+Using the GetObject function, we can perform a safe downcast
+to a DropTailQueue, where MaxPackets is a member
+@verbatim
+ Ptr<DropTailQueue> dtq = txQueue->GetObject <DropTailQueue> ();
+ NS_ASSERT (dtq);
+@end verbatim
+
+Next, we can get the value of an attribute on this queue
+We have introduced wrapper "Value" classes for the underlying
+data types, similar to Java wrappers around these types, since
+the attribute system stores values and not disparate types.
+Here, the attribute value is assigned to a Uinteger, and
+the Get() method on this value produces the (unwrapped) uint32_t.
+@verbatim
+ Uinteger limit = dtq->GetAttribute ("MaxPackets");
+ NS_LOG_INFO ("1. dtq limit: " << limit.Get () << " packets");
+@end verbatim
+
+Note that the above downcast is not really needed; we could have
+done the same using the Ptr<Queue> even though the attribute
+is a member of the subclass
+@verbatim
+ limit = txQueue->GetAttribute ("MaxPackets");
+ NS_LOG_INFO ("2. txQueue limit: " << limit.Get () << " packets");
+@end verbatim
+
+Now, let's set it to another value (60 packets)
+@verbatim
+ txQueue->SetAttribute("MaxPackets", Uinteger (60));
+ limit = txQueue->GetAttribute ("MaxPackets");
+ NS_LOG_INFO ("3. txQueue limit changed: " << limit.Get () << " packets");
+@end verbatim
+
+@subsubsection Namespace-based access
+
+An alternative way to get at the attribute is to use the configuration
+namespace. Here, this attribute resides on a known path in this
+namespace; this approach is useful if one doesn't have access to
+the underlying pointers and would like to configure a specific
+attribute with a single statement.
+@verbatim
+ Config::Set ("/NodeList/0/DeviceList/0/TxQueue/MaxPackets", Uinteger (25));
+ limit = txQueue->GetAttribute ("MaxPackets");
+ NS_LOG_INFO ("4. txQueue limit changed through namespace: " <<
+ limit.Get () << " packets");
+@end verbatim
+
+We could have also used wildcards to set this value for all nodes
+and all net devices (which in this simple example has the same
+effect as the previous Set())
+@verbatim
+ Config::Set ("/NodeList/*/DeviceList/*/TxQueue/MaxPackets", Uinteger (15));
+ limit = txQueue->GetAttribute ("MaxPackets");
+ NS_LOG_INFO ("5. txQueue limit changed through wildcarded namespace: " <<
+ limit.Get () << " packets");
+@end verbatim
+
+@node Setting through constructors and helper classes
+@subsection Setting through constructors helper classes
+
+Arbitrary combinations of attributes can be set and fetched from
+the helper and low-level APIs; either from the constructors themselves:
+@verbatim
+Ptr<Object> p = CreateObject<MyNewObject> ("n1", v1, "n2", v2, ...);
+@end verbatim
+or from the higher-level helper APIs, such as:
+@verbatim
+ mobility.SetPositionAllocator ("GridPositionAllocator",
+ "MinX", FpValue (-100.0),
+ "MinY", FpValue (-100.0),
+ "DeltaX", FpValue (5.0),
+ "DeltaY", FpValue (20.0),
+ "GridWidth", UintValue (20),
+ "LayoutType", "RowFirst");
+@end verbatim
+
+@node Value classes
+@subsection Value classes
+Readers will note the new Value classes. These can be thought of as
+an intermediate class that can be used to convert from raw types to the
+Values that are used by the system. Recall that this database is holding
+objects of many types with a single generic type. Conversions to this
+type can either be done using an intermediate class (IntValue, FpValue for
+"floating point") or via strings. Direct implicit conversion of types
+to Value is not really practical. So in the above, users have a choice
+of using strings or values:
+@verbatim
+p->Set ("cwnd", "100"); // string-based setter
+p->Set ("cwnd", IntValue(100)); // value-based setter
+@end verbatim
+
+The system provides some macros that help users declare and define
+new Value subclasses for new types that they want to introduce into
+the attribute system.
+
+@node Extending attributes
+@section Extending attributes
+
+The ns-3 system will place a number of internal values under the
+attribute system, but undoubtedly users will want to extend this
+to pick up ones we have missed, or to add their own classes to this.
+
+@subsection Adding an existing internal variable to the metadata system
+
+// XXX revise me
+
+Consider this variable in class TcpSocket:
+@verbatim
+ uint32_t m_cWnd; // Congestion window
+@end verbatim
+
+Suppose that someone working with Tcp wanted to get or set the
+value of that variable using the metadata system. If it were not
+already provided by ns-3, the user could declare the following addition
+in the metadata system (to the TypeId declaration for TcpSocket):
+@verbatim
+ .AddParameter ("Congestion window",
+ "Tcp congestion window (bytes)",
+ MakeUIntParamSpec (&TcpSocket::m_cWnd, 1));
+
+@end verbatim
+
+Now, the user with a pointer to the TcpSocket can perform operations
+such as setting and getting the value, without having to add these
+functions explicitly. Furthermore, access controls can be applied, such
+as allowing the parameter to be read and not written, or bounds
+checking on the permissible values can be applied.
+
+@subsection Adding a new TypeId
+
+Here, we discuss the impact on a user who wants to add a new class to
+ns-3; what additional things must be done to hook it into this system.
+
+We've already introduced what a TypeId definition looks like:
+@verbatim
+TypeId
+RandomWalk2dMobilityModel::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("RandomWalkMobilityModel")
+ .SetParent<MobilityModel> ()
+ .SetGroupName ("Mobility")
+ .AddConstructor<RandomWalk2dMobilityModel> ()
+ // followed by a number of Parameters
+ .AddParameter ("bounds",
+ "Bounds of the area to cruise.",
+ MakeRectangleParamSpec (&RandomWalk2dMobilityModel::m_bounds, Rectangle (0.0, 0.0, 100.0, 100.0)))
+ .AddParameter ("time",
+ "Change current direction and speed after moving for this delay.",
+ MakeTimeParamSpec (&RandomWalk2dMobilityModel::m_modeTime,
+ Seconds (1.0)))
+
+ // etc (more parameters).
+@end verbatim
+
+The declaration for this in the class declaration is one-line public
+member method:
+@verbatim
+ public:
+ static TypeId GetTypeId (void);
+@end verbatim
+
+@section Adding new class type to the Value system
+
+From the perspective of the user who writes a new class in the system and
+wants to hook it in to the attribute system, there is mainly the matter
+of writing
+the conversions to/from strings and Values. Most of this can be
+copy/pasted with macro-ized code. For instance, consider class
+Rectangle in the @code{src/mobility/} directory:
+
+One line is added to the class declaration:
+@verbatim
+/**
+ * \brief a 2d rectangle
+ */
+class Rectangle
+{
+...
+
+ VALUE_HELPER_HEADER_1 (Rectangle);
+};
+@end verbatim
+
+One templatized declaration, and two operators, are added below the
+class declaration:
+
+@verbatim
+std::ostream &operator << (std::ostream &os, const Rectangle &rectangle);
+std::istream &operator >> (std::istream &is, Rectangle &rectangle);
+
+VALUE_HELPER_HEADER_2 (Rectangle);
+@end verbatim
+
+In the class definition, the code looks like this:
+
+@verbatim
+VALUE_HELPER_CPP (Rectangle);
+
+std::ostream &
+operator << (std::ostream &os, const Rectangle &rectangle)
+{
+ os << rectangle.xMin << "|" << rectangle.xMax << "|" << rectangle.yMin << "|" << rectangle.yMax;
+ return os;
+}
+std::istream &
+operator >> (std::istream &is, Rectangle &rectangle)
+ {
+ char c1, c2, c3;
+ is >> rectangle.xMin >> c1 >> rectangle.xMax >> c2 >> rectangle.yMin >> c3 >> rectangle.yMax;
+ if (c1 != '|' ||
+ c2 != '|' ||
+ c3 != '|')
+ {
+ is.setstate (std::ios_base::failbit);
+ }
+ return is;
+}
+@end verbatim
+
+These stream operators simply convert from a string representation of the
+Rectangle ("xMin|xMax|yMin|yMax") to the underlying Rectangle, and the
+modeler must specify these operators and the string syntactical representation
+of an instance of the new class.
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/tutorial/in-process/figures/README Sat Jun 28 19:46:55 2008 -0700
@@ -0,0 +1,18 @@
+Please write image files in a vector graphics format, when possible, and
+generate the .png and .pdf versions on the fly (see ../Makefile).
+
+Currently supported tools are dia and tgif. xfig could be added similarly
+if someone wants to add it. The main requirement for adding another format
+is that the tool to edit it is freely available and that a cron script can
+autogenerate the pdf and png from the figure source.
+
+Store the .dia, or .obj versions in mercurial, but not the .png or .pdfs.
+If the figure is not available in a vector graphics format, store both
+a .png and a .pdf version in this directory.
+
+If you add a source (.dia, .obj) file here, remember to add it to
+the list of figure sources in the Makefile in the directory above
+
+Note: tgif can convert from .obj to .pdf, but the pdf that results takes
+up a whole page. Instead, we convert to an intermediate .eps step, and
+then run epstopdf.
Binary file doc/tutorial/in-process/figures/dumbbell.dia has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/tutorial/in-process/figures/helpers.obj Sat Jun 28 19:46:55 2008 -0700
@@ -0,0 +1,115 @@
+%TGIF 4.1.43-QPL
+state(0,37,100.000,0,0,0,32,1,9,1,1,0,0,1,2,1,0,'Courier',0,80640,0,2,0,10,0,0,1,1,0,16,0,0,1,1,1,1,1088,1408,1,0,2880,0).
+%
+% @(#)$Header$
+% %W%
+%
+unit("1 pixel/pixel").
+color_info(11,65535,0,[
+ "magenta", 65535, 0, 65535, 65535, 0, 65535, 1,
+ "red", 65535, 0, 0, 65535, 0, 0, 1,
+ "green", 0, 65535, 0, 0, 65535, 0, 1,
+ "blue", 0, 0, 65535, 0, 0, 65535, 1,
+ "yellow", 65535, 65535, 0, 65535, 65535, 0, 1,
+ "pink", 65535, 49344, 52171, 65535, 49344, 52171, 1,
+ "cyan", 0, 65535, 65535, 0, 65535, 65535, 1,
+ "CadetBlue", 24415, 40606, 41120, 24415, 40606, 41120, 1,
+ "white", 65535, 65535, 65535, 65535, 65535, 65535, 1,
+ "black", 0, 0, 0, 0, 0, 0, 1,
+ "DarkSlateGray", 12079, 20303, 20303, 12079, 20303, 20303, 1
+]).
+script_frac("0.6").
+fg_bg_colors('black','white').
+dont_reencode("FFDingbests:ZapfDingbats").
+page(1,"",1,'').
+text('black',272,195,2,0,1,248,36,0,13,5,0,0,0,0,2,248,36,0,0,"",0,0,0,0,208,'',[
+minilines(248,36,0,0,0,0,0,[
+mini_line(200,13,5,0,0,0,[
+str_block(0,200,13,5,0,-8,0,0,0,[
+str_seg('black','Courier',0,80640,200,13,5,0,-8,0,0,0,0,0,
+ "low-level APIs (all src/ ")])
+]),
+mini_line(248,13,5,0,0,0,[
+str_block(0,248,13,5,0,-2,0,0,0,[
+str_seg('black','Courier',0,80640,248,13,5,0,-2,0,0,0,0,0,
+ "directories except src/helper/)")])
+])
+])]).
+rcbox('black','',96,240,384,288,5,1,1,0,16,2,0,0,0,0,'1',0,[
+]).
+text('black',192,259,1,0,1,112,18,3,13,5,2,0,0,0,2,112,18,0,0,"",0,0,0,0,272,'',[
+minilines(112,18,0,0,0,0,0,[
+mini_line(112,13,5,0,0,0,[
+str_block(0,112,13,5,0,0,0,0,0,[
+str_seg('black','Courier',0,80640,112,13,5,0,0,0,0,0,0,0,
+ "ns-3 simulator")])
+])
+])]).
+poly('black','',2,[
+ 272,208,240,240],0,1,1,17,0,0,2,0,0,0,0,'1',0,0,
+ "0","",[
+ 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
+]).
+poly('black','',2,[
+ 240,176,240,240],1,1,1,18,0,0,0,0,0,0,0,'1',0,0,
+ "0","",[
+ 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
+]).
+rcbox('black','',176,128,384,176,5,1,1,0,16,25,0,0,0,0,'1',0,[
+]).
+text('black',192,131,2,0,1,120,36,26,13,5,2,0,0,0,2,120,36,0,0,"",0,0,0,0,144,'',[
+minilines(120,36,0,0,0,0,0,[
+mini_line(120,13,5,0,0,0,[
+str_block(0,120,13,5,0,-1,0,0,0,[
+str_seg('black','Courier',0,80640,120,13,5,0,-1,0,0,0,0,0,
+ "ns-3 helper API")])
+]),
+mini_line(96,13,5,0,0,0,[
+str_block(0,96,13,5,0,-2,0,0,0,[
+str_seg('black','Courier',0,80640,96,13,5,0,-2,0,0,0,0,0,
+ "(src/helper)")])
+])
+])]).
+rcbox('black','',96,16,384,64,0,1,1,0,16,32,0,0,0,0,'1',0,[
+]).
+poly('black','',2,[
+ 240,64,240,128],1,1,1,36,0,0,0,0,0,0,0,'1',0,0,
+ "0","",[
+ 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
+]).
+text('black',272,83,2,0,1,200,36,40,13,5,0,0,0,0,2,200,36,0,0,"",0,0,0,0,96,'',[
+minilines(200,36,0,0,0,0,0,[
+mini_line(200,13,5,0,0,0,[
+str_block(0,200,13,5,0,-2,0,0,0,[
+str_seg('black','Courier',0,80640,200,13,5,0,-2,0,0,0,0,0,
+ "helper APIs (src/helper/)")])
+]),
+mini_line(192,13,5,0,0,0,[
+str_block(0,192,13,5,0,-1,0,0,0,[
+str_seg('black','Courier',0,80640,192,13,5,0,-1,0,0,0,0,0,
+ "call into low-level APIs")])
+])
+])]).
+poly('black','',2,[
+ 272,96,240,128],0,1,1,41,0,0,2,0,0,0,0,'1',0,0,
+ "0","",[
+ 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
+]).
+text('black',128,19,2,0,1,232,36,47,13,5,0,0,0,0,2,232,36,0,0,"",0,0,0,0,32,'',[
+minilines(232,36,0,0,0,0,0,[
+mini_line(224,13,5,0,0,0,[
+str_block(0,224,13,5,0,-2,0,0,0,[
+str_seg('black','Courier',0,80640,224,13,5,0,-2,0,0,0,0,0,
+ "ns-3 scripts (main programs)")])
+]),
+mini_line(232,13,5,0,0,0,[
+str_block(0,232,13,5,0,-1,0,0,0,[
+str_seg('black','Courier',0,80640,232,13,5,0,-1,0,0,0,0,0,
+ "- may use either or both APIs")])
+])
+])]).
+poly('black','',2,[
+ 144,64,144,240],1,1,1,50,0,0,0,0,0,0,0,'1',0,0,
+ "0","",[
+ 0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
+]).
Binary file doc/tutorial/in-process/figures/oneobj.png has changed
Binary file doc/tutorial/in-process/figures/pp.dia has changed
Binary file doc/tutorial/in-process/figures/star.dia has changed
Binary file doc/tutorial/in-process/figures/threeobj.png has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/tutorial/in-process/helpers.texi Sat Jun 28 19:46:55 2008 -0700
@@ -0,0 +1,20 @@
+@node Helper Functions
+@chapter Helper Functions
+@anchor{chap:Helpers}
+This chapter describes an intermediate API for the simulator; what we
+call the "helper API". The helper API is implemented in
+@code{src/helper/} directory; it depends on (and wraps) the low-level
+API which is implemented everywhere else in @code{src/}. The following
+figure shows this relationship.
+@center @image{figures/helpers,,,,png}
+
+The use of the helper API is optional. It has two main goals:
+@itemize @bullet
+@item Provide "syntactic sugar" to wrap a number of related low-level
+API calls together, that would normally be grouped together often, into
+something that is more user-friendly.
+@item Handle configuration of larger topological units (e.g., a set
+of nodes or a set of nodes on a particular link) .
+@end itemize
+
+(more to follow)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/tutorial/in-process/introduction.texi Sat Jun 28 19:46:55 2008 -0700
@@ -0,0 +1,2034 @@
+
+@c ========================================================================
+@c Begin document body here
+@c ========================================================================
+
+@c ========================================================================
+@c Tutorial Goals
+@c ========================================================================
+
+@node Tutorial Goals
+@unnumbered Tutorial Goals
+
+@c This is an unnumbered section, like a preface. Numbering
+@c starts with section 1 (Introduction)
+
+The goal of this ns-3 tutorial is to introduce new users of ns-3 to enough
+of the system to enable them to author simple simulation scripts and extract
+useful information from the simulations. We begin by introducing some of the
+other important resources that are available to those interested in using or
+writing scripts, models and even those interested in making contributions to
+the core ns-3 system. We provide an overview of some of the
+important abstractions, design patterns and idioms used when writing
+ns-3 scripts, and then dig right in by begining to write simulation
+scripts, run them and interpret results.
+
+After completing this tutorial, one should be able to:
+@itemize @bullet
+@item Find documentation resources in the distribution and on the web;
+@item Download and compile the ns-3 system;
+@item Understand the key software conventions of ns-3;
+@item Modify configuration parameters of existing scripts;
+@item Change the simulation output (tracing, logging, statistics);
+@item Extend the simulator to use new objects
+@item Write new ns-3 applications;
+@item See how to port code from ns-2;
+@item ... (more to follow)
+@end itemize
+
+@c ========================================================================
+@c PART: Introduction
+@c ========================================================================
+@c The below chapters are under the major heading "Introduction"
+@c This is similar to the Latex \part command
+@c
+@c ========================================================================
+@c Overview
+@c ========================================================================
+@node Overview
+@chapter Overview
+
+@menu
+* For ns-2 users::
+* Contributing::
+* Tutorial organization::
+@end menu
+
+The ns-3 simulator is a discrete-event network
+simulator targeted primarily for research and educational use.
+The @uref{http://www.nsnam.org,,ns-3 project}, started in
+2006, is an open-source project. The goal of the project is to
+build a new network simulator primarily for research and educational use.
+
+Primary documentation for the 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
+
+The purpose of this tutorial is to introduce new ns-3 users to the
+system in a structured way. It is sometimes difficult for new users to
+glean essential information from detailed manuals and to convert this
+information into working simulations. In this tutorial, we will build
+several example simulations, introducing and explaining key concepts and
+features as we go.
+
+As the tutorial unfolds, we will introduce the full ns-3
+documentation
+and provide pointers to source code for those interested in delving deeper
+into the workings of the system.
+
+A few key points are worth noting at the onset:
+@itemize @bullet
+@item ns-3 is not an extension of @uref{http://www.isi.edu/nsnam/ns,,ns-2};
+it is a new
+simulator. The two simulators are both written in C++ but ns-3
+is a new simulator that does not support the ns-2 APIs.
+Some models from ns-2 have already been ported from ns-2
+to ns-3. The project will continue to maintain ns-2 while
+ns-3 is being built, and will study transition and
+integration mechanisms.
+@item ns-3 is open-source, and the project strives to maintain
+an open environment for researchers to contribute and share their
+software.
+@end itemize
+
+@node For ns-2 users
+@section For ns-2 users
+
+For those familiar with ns-2, the most visible outward change
+when moving to ns-3 is the choice of scripting language.
+ns-2 is typically scripted in Tcl and results of simulations can
+be visualized using the Network Animator @command{nam}. In
+ns-3 there is currently no visualization module, and Python
+bindings have been developed (Tcl bindings have been prototyped
+using @uref{http://www.swig.org,,SWIG}, but are not supported by the
+current development team).
+In this tutorial, we will concentrate on
+scripting directly in C++ and interpreting results via trace files.
+
+But there are similarities as well (both, for example, are based
+on C++ objects, and some code from ns-2 has already been ported
+to ns-3). We will try to highlight differences between ns-2 and ns-3
+as we proceed in this tutorial.
+
+@node Contributing
+@section Contributing
+
+@cindex software configuration management
+ns-3 is a research and educational simulator, by and for the
+research community. It will rely on the ongoing contributions of
+the community to develop new models, debug or maintain
+existing ones, and share results. There are a few policies
+that we hope will encourage people to contribute to ns-3 like they
+have for ns-2:
+@itemize @bullet
+@item open source licensing based on GNU GPLv2 compatibility
+@item @uref{http://www.nsnam.org/wiki/index.php,,wiki}
+@item @uref{http://www.nsnam.org/wiki/index.php/Contributed_Code,,Contributed Code} page, similar to ns-2's popular
+@uref{http://nsnam.isi.edu/nsnam/index.php/Contributed_Code,,Contributed Code}
+page
+@item @code{src/contrib} directory (we will host your contributed code)
+@item open @uref{http://www.nsnam.org/bugzilla,,bug tracker}
+@item ns-3 developers will gladly help potential contributors to get
+started with the simulator (please contact @uref{http://www.nsnam.org/people.html,,one of us})
+@end itemize
+
+If you are an ns user, please consider to provide your feedback,
+bug fixes, or code to the project.
+
+@node Tutorial organization
+@section Tutorial organization
+
+The tutorial assumes that new users might follow a path such as follows:
+
+@itemize @bullet
+@item browse the source code and documentation, to get a feel for
+the simulator and what it might be like to handle;
+@item try to download and build a copy;
+@item try to run a few sample programs, and perhaps change some configurations;
+@item look at simulation output, and try to adjust it
+@item study the software architecture of the system, to consider hacking it or
+extending it;
+@item write new models or port existing code to ns-3, and eventually post those
+models back to the community.
+@end itemize
+
+As a result, we have tried to organize the tutorial along the above
+broad sequences of events.
+
+@c ========================================================================
+@c Browsing ns-3
+@c ========================================================================
+
+@node Browsing
+@chapter Browsing ns-3
+
+@menu
+* Source code::
+* Doxygen::
+* Other documentation::
+@end menu
+
+@node Source code
+@section Source code
+
+The most recent code can be browsed on our web server at the following link:
+@uref{http://code.nsnam.org/?sort=lastchange}. If you click on the bold
+repository names on the left of the page, you will see changelogs for
+these repositories, and links to the @emph{manifest}. From the manifest
+links, one can browse the source tree.
+
+The top-level directory will look something like:
+@verbatim
+ AUTHORS RELEASE_NOTES examples/ src/ waf*
+ LICENSE VERSION ns3/ tutorial/ waf.bat*
+ README doc/ samples/ utils/ wscript
+@end verbatim
+The source code is mainly in the @code{src} directory. Example
+scripts are in the @code{examples} directory. Both are good directories
+to start browsing some code.
+
+For ns-2 users, who may be familiar with the @code{simple.tcl} example script
+in the ns-2 documentation, an analogous script is found in
+@code{examples/simple-point-to-point.cc} with a Python equivalent found
+in @emph{(pending Python merge)}.
+
+@node Doxygen
+@section Doxygen
+
+We document all of APIs using @uref{http://www.stack.nl/~dimitri/doxygen/,,Doxygen}. Current builds of this documentation are available at:
+@uref{http://www.nsnam.org/doxygen/index.html}, which are worth an initial
+look.
+
+@node Other documentation
+@section Other documentation
+
+See: @uref{http://www.nsnam.org/documents.html}.
+
+@c ========================================================================
+@c Resources
+@c ========================================================================
+
+@node Resources
+@chapter Resources
+
+@menu
+* The-Web::
+* Mercurial::
+* Waf::
+* Environment-Idioms-Design-Patterns::
+* Socket-Programming::
+@end menu
+
+@node The-Web
+@section The Web
+
+@cindex www.nsnam.org
+There are several important resources of which any ns-3 user must be
+aware. The main web site is located at @uref{http://www.nsnam.org}
+and provides access to basic information about the ns-3 system.
+Detailed documentation is available through the main web site at
+@uref{http://www.nsnam.org/documents.html}.
+
+@cindex documentation
+@cindex architecture
+You can find documents relating to the system architecture from this page,
+and also gain access to the detailed software documentation. The software
+system is documented in great detail using
+@uref{http://www.stack.nl/~dimitri/doxygen/,,Doxygen}. There is a Wiki that
+complements the main ns-3 web site which you will find at
+@uref{http://www.nsnam.org/wiki/}.
+
+You will find user and developer FAQs there as well as troubleshooting guides,
+third-party contributed code, papers, etc. The source code may be found
+and browsed at @uref{http://code.nsnam.org/}.
+
+@cindex repository!ns-3-dev
+@cindex repository!releases
+There you will find the current development tree in the repository named
+@code{ns-3-dev}. Past releases and experimental repositories of the core
+developers may also be found there.
+
+@node Mercurial
+@section Mercurial
+
+Complex software systems need some way to manage the organization and
+changes to the underlying code and documentation. There are many ways to
+perform this feat, and you may have heard of some of the systems that are
+currently used to do this. The Concurrent Version System (CVS) is probably
+the most well known.
+
+@cindex software configuration management
+@cindex Mercurial
+The ns-3 project uses Mercurial as its source code management system.
+Although you do not need to know much about Mercurial in order to complete
+this tutorial, we recommend becoming familiar with Mercurial and using it
+to access the source code. Mercurial has a web site at
+@uref{http://www.selenic.com/mercurial/},
+from which you can get binary or source releases of this Software
+Configuration Management (SCM) system. Selenic (the developer of Mercurial)
+also provides a tutorial at
+@uref{http://www.selenic.com/mercurial/wiki/index.cgi/Tutorial/},
+and a QuickStart guide at
+@uref{http://www.selenic.com/mercurial/wiki/index.cgi/QuickStart/}.
+
+You can also find vital information about using Mercurial and ns-3
+on the main ns-3 web site.
+
+@node Waf
+@section Waf
+
+@cindex Waf
+@cindex make
+@cindex build
+Once you have source code downloaded to your local system, you will need
+to compile that source to produce usable programs. Just as in the case of
+source code management, there are many tools available to perform this
+function. Probably the most famous of these tools is @code{make}. Along
+with being the most famous, @code{make} is probably the most difficult to
+use in a very large and highly configurable system. Because of this, many
+alternatives have been developed. Recently these systems have been developed
+using the Python language.
+
+The build system @code{Waf} is used on the ns-3 project. It is one
+of the new generation of Python-based build systems. You will not need to
+understand any Python to build the existing ns-3 system, and will
+only have to understand a tiny and intuitively obvious subset of Python in
+order to extend the system in most cases.
+
+For those interested in the gory details of Waf, the main web site can be
+found at @uref{http://freehackers.org/\~tnagy/waf.html}.
+
+@node Environment-Idioms-Design-Patterns
+@section Environment, Idioms, and Design Patterns
+
+@cindex C++
+As mentioned above, scripting in ns-3 is done in C++. A working
+knowledge of C++ and object-oriented concepts is assumed in this document.
+We will take some time to review some of the more advanced concepts or
+possibly unfamiliar language features, idioms and design patterns as they
+appear. We don't want this tutorial to devolve into a C++ tutorial, though,
+so we do expect a basic command of the language. There are an almost
+unimaginable number of sources of information on C++ available on the web or
+in print.
+
+If you are new to C++, you may want to find a tutorial- or cookbook-based
+book or web site and work through at least the basic features of the language
+before proceeding.
+
+@subsection Environment
+
+@cindex toolchain
+@cindex GNU
+The ns-3 system uses the GNU ``toolchain'' for development.
+A software toolchain is the set of programming tools available in the given
+environment. For a quick review of what is included in the GNU toolchain see,
+@uref{http://en.wikipedia.org/wiki/GNU_toolchain}.
+
+@cindex Linux
+Typically an ns-3 author will work in Linux or a Linux-like
+environment. For those running under Windows, there do exist environments
+which simulate the Linux environment to various degrees. The ns-3
+project supports development in the Cygwin and the MinGW environments for
+these users. See @uref{http://www.cygwin.com/} and
+@uref{http://www.mingw.org/} for details on downloading and using these
+systems. Cygwin provides many of the popular Linux system commands.
+It can, however, sometimes be problematic due to the way it
+actually does its emulation, and sometimes interactions with other Windows
+software can cause problems.
+
+@cindex Cygwin
+@cindex MinGW
+If you do use Cygwin or MinGW; and use Logitech products, we will save you
+quite a bit of heartburn right off the bat and encourage you to take a look
+at the @uref{http://www.mingw.org/MinGWiki/index.php/FAQ,,MinGW FAQ}.
+
+@cindex Logitech
+Search for ``Logitech'' and read the FAQ entry, ``why does make often
+crash creating a sh.exe.stackdump file when I try to compile my source code.''
+Believe it or not, the @code{Logitech Process Monitor} insinuates itself into
+every DLL in the system when it is running. It can cause your Cygwin or
+MinGW DLLs to die in mysterious ways and often prevents debuggers from
+running. Beware of Logitech.
+
+@subsection Idioms and Design Patterns
+
+@cindex idiom
+In any system, there are a number of problems to be solved that happen
+repeatedly. Often the solutions to these problems can be generalized and
+applied in a similar way across the system. These solutions are called
+Design Patterns. The ns-3 system relies on several classic design
+patterns.
+
+@cindex design pattern
+Also, in any language, there are constructs that, while they aren't part of the
+language per se, are commonly found and useful. For example, at the lowest
+level a C programmer should be able to immediately recognize the purpose and
+intent of the following code without having to reflect on the details:
+
+@verbatim
+ for (;;)
+@end verbatim
+
+These low-level constructs, or idioms, extend upward in complexity, eventually
+becoming implementations of design patterns. As you are exposed to more
+and more of the ns-3 system, you will begin to recognize and be
+comfortable with the C++ implementations (idioms) of several important design
+patterns.
+
+@cindex functor
+@cindex callback
+@cindex smart pointer
+The ns-3 code relies heavily on
+@emph{Generalized Functors, Callbacks,
+Smart Pointers, Singletons, and Object Factories}. Although we will
+not assume any detailed knowledge of the idioms and design patterns used
+in the ns-3
+system, it will be useful for readers who intend to delve deeply into the
+system to understand some important related concepts. We recommend two
+resources: @uref{http://www.amazon.com/Design-Patterns-Object-Oriented-Addison-Wesley-Professional/dp/0201633612/,,Design Patterns: Elements of Reusable Object-Oriented Software, Gamma et. al.} and
+@uref{http://www.amazon.com/exec/obidos/ASIN/0201704315,,Modern C++ Design: Generic Programming and Design Patterns Applied, Alexandrescu}.
+
+Gamma addresses the abstract design patterns, and Alexandrescu addresses the
+C++ idioms you will often see throughout the ns-3 code.
+
+@cindex template
+Almost any use of ns-3 will require some basic knowledge of C++
+templates.
+We will discuss the high-level uses in this tutorial. However, if you venture
+deeply into the source code, you will see fairly heavy use of relatively
+sophisticated C++ templates in some of low-level modules of the system. The
+You don't have to be a template guru to complete this tutorial but if you
+expect to work in ns-3 within the simulation core, you will have to be
+somewhat fluent
+with templates. If you want to truly grok C++ templates we recommend,
+@uref{http://www.amazon.com/Templates-Complete-Guide-David-Vandevoorde/dp/0201734842/,,C++ Templates: The Complete Guide, Vandevoorde and Josuttis}.
+
+@node Socket-Programming
+@section Socket Programming
+
+@cindex sockets
+We will assume a basic facility with the Berkeley Sockets API in the examples
+used in this tutorial. If you are new to sockets, we recommend reviewing the
+API and some common usage cases. For a good overview of programming TCP/IP
+sockets we recommend @uref{http://www.elsevier.com/wps/product/cws_home/680765,,Practical TCP/IP Sockets in C, Donahoo and Calvert}.
+
+There is an associated web site that includes source for the examples in the
+book, which you can find at:
+@uref{http://cs.baylor.edu/~donahoo/practical/CSockets/}.
+
+If you understand the first four chapters of the book (or for those who do
+not have access to a copy of the book, the echo clients and servers shown in
+the website above) you will be in good shape to understand the tutorial.
+There is a similar book on Multicast Sockets,
+@uref{http://www.elsevier.com/wps/product/cws_home/700736,,Multicast Sockets, Makofske and Almeroth}.
+that covers material you may need to understand for the multicast examples.
+
+@c ========================================================================
+@c Downloading and Compiling
+@c ========================================================================
+
+@node Downloading and Compiling
+@chapter Downloading and Compiling
+
+@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/}.
+
+The developers attempt to keep this repository in a consistent, working state
+but it is a development area with unreleased code present, so you may want to
+consider downloading an official release.
+
+There will be a number of released repositories present at code.nsnam.org.
+These repos will have names like ns-3.0.1 --- which referes to release 3.0.1
+of the network simulator (or if you like, release 0.1 of ns-3).
+Since the releases are changing at a rate of one per month, I will stick with
+the more constant ns-3-dev here, but you can replace the string ns-3-dev with
+your choice of release (e.g., ns-3.0.5) below. You can find the latest
+version of the code either by inspection of the repository list or by going
+to the ``Getting Started'' web page and looking for the latest release
+identifier.
+
+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 1513 changesets with 5687 changes to 733 files
+ 358 files updated, 0 files merged, 0 files removed, 0 files unresolved
+@end verbatim
+
+After the clone command completes, you should have a directory called
+ns-3-dev under your @code{~/repos} directory, the contents of which should
+look something like the following:
+
+@verbatim
+ AUTHORS RELEASE_NOTES examples/ src/ waf*
+ LICENSE VERSION ns3/ tutorial/ waf.bat*
+ README doc/ samples/ utils/ wscript
+@end verbatim
+
+You are now ready to build the ns-3 distribution.
+
+@section Building
+@cindex Waf!build
+@cindex Waf!configure
+@cindex Waf!debug
+@cindex Waf!compile
+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 program cpp : ok /usr/bin/cpp
+ Checking for program ar : ok /usr/bin/ar
+ Checking for program ranlib : ok /usr/bin/ranlib
+ Checking for compiler could create programs : ok
+ Checking for compiler could create shared libs : ok
+ Checking for compiler could create static libs : ok
+ Checking for flags -Wall : ok
+ Checking for flags -O2 : ok
+ Checking for flags -g -DDEBUG : ok
+ Checking for flags -g3 -O0 -DDEBUG : ok
+ Checking for g++ : ok
+ Checking for header stdlib.h : ok
+ Checking for header stdlib.h : ok
+ Checking for header signal.h : ok
+ Checking for high precision time implementation: 128-bit integer
+ Checking for header stdint.h : ok
+ Checking for header inttypes.h : ok
+ Checking for header sys/inttypes.h : not found
+ Configuration finished successfully; project is now ready to build.
+ ~/repos/ns-3-dev >
+@end verbatim
+
+The build system is now configured and you can build the debug versions of
+the 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
+
+and you will see a number of software unit tests subsequently execute.
+
+@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.}
+
+@c ========================================================================
+@c Some Prerequisites
+@c ========================================================================
+
+@node Some-Prerequisites
+@chapter Some Prerequisites
+
+The first thing we need to do before actually starting to code is to explain
+a few core concepts, abstractions and idioms in the system. Much of this may
+appear transparently obvious to some, but we recommend taking the time to read
+through this chapter just to ensure you are starting on a firm foundation.
+
+@section Abstractions
+
+In this section, we'll review some terms that are commonly used in
+networking, but have a specific meaning in 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
+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 a @code{NetDevice} to a @code{Node}, and a @code{NetDevice}
+to a @code{Channel} is such a common task in ns-3 we provide what we
+call @emph{topology helpers} to make this as easy as possible. Topology
+helpers perform much of the dirty work of creating and connecting net devices.
+For example, it may take several distinct method calls to create a NetDevice,
+add a MAC address, connect the net device to a @code{Node} and configure
+the protocol stack, and then connect the @code{NetDevice} to a @code{Channel}.
+We use topology helper functions to compose those distinct operations into
+an easy to use model.
+
+Topology helper functions use the abstractions (described above) of Network
+Interface Cards and Cables. When you think of adding a new kind of network,
+you may think of going out to the local computer retailer and buying a kit.
+This kit might include a nework cable and some number of peripheral cards and
+thier associated software drivers. You can think of topology helpers in
+roughly the same way. Instead of buying a kit for a given type of network,
+you will use a topology helper class for a given type of network, to accomplish
+the equivalent of installing the network ``kit.''
+
+@section Important Idioms
+Now that we have identified that there are C++ classes in the system called
+@code{Node} and @code{InternetNode}, we need to understand how to bring
+objects of these classes into existance, and manage their lifetimes. Let's
+examine this in some detail here.
+
+@cindex InternetNode
+@cindex CreateObject
+@cindex Ptr
+In ns-3, if we want to create an @code{InternetNode} in a
+script, we will
+typically do something like the following example:
+
+@verbatim
+ Ptr<Node> p = CreateObject<InternetNode> ();
+@end verbatim
+
+@cindex smart pointer
+To some, it may seem intuitively obvious that we're creating an
+@code{InternetNode} object and assigning responsibility for managing the
+object to a smart pointer named @code{p}. For the rest of us, there may be
+a lot in that line that is unfamiliar, so let's look at what this line means
+in some detail.
+
+@subsection Templates 101
+@cindex template
+If you are familiar with C++ templates, you may skip this section as it is
+just a cursory introduction to function and class templates.
+
+Referring back to the example line of code, reproduced below for your
+convenience, the angle brackets you see in the code indicate that we are
+using C++ @emph{templates}.
+
+@verbatim
+ Ptr<Node> p = CreateObject<InternetNode> ();
+@end verbatim
+
+The purpose of templates is to allow a programmer to write one version of code
+that is applicable over multiple types. Some people consider templates to be
+an enhancement of the C preprocessor macro functionality. At some level
+this comparison reveal some similarities, but C++ templates are really
+quite different.
+
+@cindex template!declaration
+@cindex template!definition
+@cindex template!use
+In C++, just as with most language constructs, templates are @emph{declared},
+@emph{defined} and @emph{used}. A declaration of a template might look
+something like,
+
+@verbatim
+ template <typename T> T Add (T first, T second);
+@end verbatim
+
+@cindex template!typename
+This line uses the keyword @code{template} followed by a declaration of a
+type name (in this case @code{T}) in angle brackets. The angle brackets
+should indicate to you that a template is being declared, defined or used.
+The type name @code{T} can be thought of as a string that will be substitited
+during the use phase of the template. For example, the @code{T} may be
+replaced by the word @code{int}. It is this substitution that leads people
+to compare templates with macros.
+
+Without going into too much more detail, this snippet declares that a piece
+of code exists that will be able to call a function @code{Add} that will
+add arbitrary types together. The @code{T} will be eventually replaced by
+a C++ data type name. For example,
+
+@verbatim
+ T Add (T first, T second);
+@end verbatim
+
+might eventually become
+
+@verbatim
+ int Add (int first, int second);
+@end verbatim
+
+If the template has been declared, we need to @emph{define} what that piece of
+code will actually do. That might look something like,
+
+@verbatim
+ template <typename T>
+ T Add (T first, T second)
+ {
+ return first + second;
+ }
+@end verbatim
+
+All we've done here is to provide an implementation of the template that
+adds the two variables together and returns the result. Note that this
+implementation works for any type that provides an @code{operator+}.
+
+The puzzle all comes together when you understand that @emph{using} a template
+causes the compiler to automatically instantiate code for a specific function
+according to the given template parameters. You might use the above template
+like,
+
+@verbatim
+ int x, y, z;
+ z = Add<int> (x, y);
+@end verbatim
+
+@cindex template!instantiate
+When the compiler sees @code{Add<int>} it understands that it needs to make
+sure that code is instantiated (created) to perform the @code{Add} using the
+specified type @code{<int>}. To a first approximation, the compiler will
+replace the typename @code{T} with the specified type @code{int} and
+automagically generate code equivalent to,
+
+@verbatim
+ int Add (int first, int second)
+ {
+ return first + second;
+ }
+@end verbatim
+
+A user of the template definition could just as easily have provided a use
+that assigned the type float. This would simply be done like,
+
+@verbatim
+ float x, y, z;
+ z = Add<float> (x, y);
+@end verbatim
+
+In this case, the compiler would automatically generate code that looked like,
+
+@verbatim
+ float Add (float first, float second)
+ {
+ return first + second;
+ }
+@end verbatim
+
+@cindex template!function
+This particular kind of template programming uses what are called
+@emph{function templates}. They are called function templates since you
+are @emph{templating} function declarations and definitions.
+
+@cindex template!class
+Templates can also be used in conjunction with classes, in which case you are
+said to be using, not too surprisingly, @emph{class templates}. The syntax and
+use is similar. To declare a class template you might use something like,
+
+@verbatim
+ template <typename T>
+ class MyStack
+ {
+ void Push (T data);
+ T Pop (void);
+ };
+@end verbatim
+
+The methods can be defined separately in a method similar to function template
+definitions,
+
+@verbatim
+ template <typename T> void MyStack<T>::Push (T data)
+ {
+ ...
+ };
+@end verbatim
+
+You can then use the new templated class in the following way,
+
+@verbatim
+ int x, y;
+
+ MyStack<int> stack;
+ stack.Push (x);
+ y = stack.Pop ();
+@end verbatim
+
+Similarly to the function template case, the compiler knows that it has to
+automatically generate code to fill out the class and method declarations
+and definitions using the appropriate type specified by @code{<int>}.
+
+@node Smart Pointers 101
+@subsection Smart Pointers 101
+If you are familiar with C++ smart pointers, you may skip this section as it
+is just a cursory introduction to smart pointers and intrusive reference
+counting.
+
+@cindex smart pointer
+Referring back to the example line of code, partially reproduced below for
+your convenience below, the left hand side is the declaration and
+initialization of a class template that implements a @emph{smart pointer}.
+
+@verbatim
+ Ptr<Node> p = ...
+@end verbatim
+
+To a first approximation, you can think of @code{Ptr<Node>} as the a new kind
+of declaration of a pointer to a @code{Node} object. The difference is that
+a smart pointer is a user-defined data type (instantiated via a templated
+class) that @emph{simulates} a classical pointer but provides additional
+features. As an aside, you typically pronounce @code{Ptr<Node>} as
+``pooter node'' where pooter rhymes with footer.
+
+@cindex memory management
+One of the most important ``additional feature'' provided by smart pointers is
+automatic memory management. Since you now understand class templates, you
+will understand how the template allows us to write the pointer code once, but
+allows us to point to many different kinds of objects. Later in the tutorial
+you will see variations such as @code{Ptr<Ipv4>} and @code{Ptr<Channel>},
+which are smart pointers to an IP version 4 object and a channel object,
+respectively.
+
+The use of built-in pointers in C and C++ is a major source of bugs. Constant
+allocation of, passing of responsibility for, and deallocation of underlying
+data makes it very likely that errors will occur. In one of these errors,
+the usual problem is that the responsibility for deallocating a memory block
+is misplaced. This may result in a memory leak or a duplicate deallocation.
+Smart pointers try to prevent this kind of problem by working with the
+@emph{scope} and @emph{extent} rules of the language to make memory
+deallocation automatic.
+
+The scope of a variable defines where in a program a given variable may be
+referred to. The extent of a variable defines when in the program's execution
+the variable has a valid value. Consider a simple subroutine that contains a
+smart pointer.
+
+@verbatim
+ void SimpleSubroutine (void)
+ {
+ Ptr<Node> p;
+ }
+@end verbatim
+
+@cindex scope
+The variable named @code{p} has a scope limited to the subroutine itself. The
+variable is said to @emph{come into scope} as the subroutine is entered during
+execution. At this time, the constructor of the underlying class is executed
+and a valid variable is available for use. When the subroutine is done
+executing, the variable is said to @emph{go out of scope}. This causes the
+destructor of the underlying class to be executed and the variable no longer
+has a valid value. This is not a problem since it is no longer valid to refer
+to the parameter. Smart pointers take advantage of these defined actions at
+points where variables must be valid and become discardable to determine when
+underlying data can be freed.
+
+@cindex reference counting!intrusive
+The ns-3 smart pointer mechanism uses a mechanism called intrusive
+reference counting to determine when a memory block should be automatically
+deallocated. The term ``intrusive'' means that a reference count (a count of
+variables required to have valid data) is stored in the object being managed
+instead of in a proxy object. This means that each piece of memory managed by
+a ns-3 smart pointer includes a reference count. When a smart
+pointer to a reference counted object is created, this reference count is
+incremented. This indicates that a new variable requires a valid data object
+be present. When a smart pointer to a reference counted object is destroyed
+(for example, when going out of scope) the reference count of the managed
+object is decremented. When the reference count goes to zero it means that
+all smart pointers to the underlying object have gone out of scope and the
+object is no longer needed by any past ``users'' of the object. This in turn
+means that the object can be safely deallocated, and this is done
+automatically for you as the ``last'' smart pointer goes out of scope.
+
+Consider how this might work as you pass a smart pointer to an object down
+a protocol stack. At each level of the stack, you pass the smart pointer
+by value. This causes a copy of the smart pointer to be made, which
+increments the reference count of the underlying object. When the
+@emph{calling} method is done executing, the calling smart pointer goes out of
+scope and the reference count is decremented. This leaves the single smart
+pointer in the @emph{called} method with a reference to the underlying object.
+When the smart pointer in the called method goes out of scope, the destructor
+for the smart pointer is called. The destructor checks the reference count
+of the underlying object and sees that it becomes zero. This indicates that
+the object can be deallocated, and the destructor does so. This results in
+the lifetime management of the underlying object being automatically managed,
+a boon if you have experience with ``manual'' memory management and finding
+memory leaks.
+
+Now, we want to make this feature available as widely as possible to objects
+in the ns-3 system. The basic operations of the smart pointer class
+are the same across any intrusively reference counted object. C++ provides a
+mechanism to achieve this kind of generic behavior --- the template. Let's
+examine the declaration of the smart pointer in more detail. First consider
+the way you might declare and use a built-in pointer. For the sake of
+simplicity, just assume that a C++ object of the class @code{MyClass} exists.
+Further assume that @code{MyClass} provides one method called @code{method}.
+Using built-in pointers, you could do something like the following:
+
+@verbatim
+ MyClass *p = ...
+ p->method ();
+@end verbatim
+
+@cindex smart pointer
+One of the key design points of smart pointers is that they should simulate
+built-in pointers. In C++ this is done by overloading @code{operator->},
+@code{operator=} and @code{operator*}. To implement a smart pointer we need
+to provide a generic class that implements these operators. This generic
+class should allow operations that appear as if it were a built-in pointer
+to the reference counted object. Typically this is accomplished via a
+relatively simple C++ class template. If you are interested in the details
+of how this may be accomplished, see Alexandrescu for a good treatment,
+
+@cindex template
+Taking the template as given, in order to declare a smart pointer you will
+need to create a smart pointer object and provide the template parameter
+needed to instantiate the required code. This parameter will be the name
+of the reference counted class to which you want to point. The smart
+pointer class overrides @code{operator=} which allows initialization of the
+smart pointer just as if it were a built-in pointer. The end result is that
+you use smart pointers just as if they were built-in pointers:
+
+@verbatim
+ SmartPointer<MyClass> p = ...
+ p->method ();
+@end verbatim
+
+@node Object Creation
+@subsection Object Creation
+@cindex CreateObject
+On the right hand side of the line of code we're examining (reproduced below
+for convenience) is the creation of an @code{InternetNode} object.
+
+@verbatim
+ ... = CreateObject<InternetNode> ();
+@end verbatim
+
+@cindex template!function
+This turns out to be an instance of use of a C++ @emph{function template}. The
+definition of the @code{CreateObject<typename T>()} template calls the new
+operator to create an object of the type T. It then creates a new smart
+pointer of the appropriate type (i.e., @code{Ptr<T>}). This new smart
+pointer is assigned initial responsibility for the new object which has its
+reference count set to one.
+
+Since the underlying creation mechanism is via the @code{new} operator, and
+you can pass parameters to the constructor for an object, we provide several
+templates that you can use for passing parameters to the object constructors.
+If the constructor for the object requires a parameter, you simply pass that
+parameter to the @code{Create} function like this,
+
+@verbatim
+ int parm = 1;
+ ... = CreateObject<MyClass> (parm);
+@end verbatim
+
+We provide Create templates with up to seven parameters, so you could
+conceivably use the @code{Create} template in situations such as,
+
+@verbatim
+ int parm = 1;
+ ... = CreateObject<MyClass> (p1, p2, p3, p4, p5, p6, p7);
+@end verbatim
+
+@subsection Type Safety
+Lets take one final look at the now infamous example line of code that we
+have been examining for some time (again reproduced below).
+
+@verbatim
+ Ptr<Node> p = CreateObject<InternetNode> ();
+@end verbatim
+
+@cindex smart pointer
+@cindex Node
+@cindex Create
+You may have noticed that the smart pointer on the left hand side of the
+assignment is associated with the type @code{Node} and the @code{Create}
+template on the right hand side creates an @code{InternetNode} object and
+returns a @code{Ptr<InternetNode>} smart pointer. For this assignment of a
+@code{Ptr<InternetNode>} to a @code{Ptr<Node>} to work, there must be some
+kind of type conversion going on.
+
+@cindex implicit conversion
+Many programmers use @code{implicit conversions} without even realizing it
+since they are sometimes so intuitive. For example, in the following code,
+
+@verbatim
+ int i = 1;
+ double d = 2.;
+ if (n == d) ...
+@end verbatim
+
+@cindex standard conversion
+the integer (1) is implicitly converted to a double (1.) before the comparison
+takes place. This conversion is performed using what is known as a C++
+@emph{standard conversion}. There are a number of standard conversions defined
+by the C++ standard. Among them are,
+
+@itemize @bullet
+@item Integral Promotions
+@item Integral Conversions
+@item Floating Conversions
+@item Pointer Conversions
+@item Reference Conversions
+@end itemize
+
+@cindex assignment operator
+@cindex Ptr
+For the case of interest here, we need to know what happens in the
+assignment operator (@code{operator=}) of our smart pointer @code{Ptr<Node>}.
+This operator takes a reference to a @code{Ptr<Node>} and not a reference to
+a @code{Ptr<InternetNode>}. The one situation where this works automatically
+in C++ is if the ``destination'' reference is to a visible, unambiguous base
+class of the ``source'' reference. In this case, the underlying pointer is
+@emph{cast} from one type to the other automatically.
+
+To summarize: The magic happens in the assignment operator. Class
+@code{InternetNode} inherits from class @code{Node}. The reference to the
+@code{InternetNode} object in question is, in essence, a pointer to an
+@code{InternetNode} object. The @code{InternetNode} class inherits from the
+@code{Node} base class in a way that makes @code{Node} visible and unambiguous.
+Therefore, there exists a standard conversion from an @code{InternetNode *}
+to a @code{Node *} and by extension from an @code{InternetNode &} to a
+@code{Node &}. This conversion is applied automatically (and invisibly)
+during paramater passing in the assignment operator we are examining.
+
+@cindex base class
+This is a rather involved way of saying there's an invisible pointer cast
+to a base class happening in the assignment. That means that
+
+@verbatim
+ Ptr<Node> p = CreateObject<InternetNode> ();
+@end verbatim
+
+or,
+
+@verbatim
+ Ptr<Channel> p = CreateObject<CsmaChannel> ();
+@end verbatim
+
+will work just fine. Of course, if you try something @emph{bad} (TM), like:
+
+@verbatim
+ Ptr<Node> p = CreateObject<CsmaChannel> ();
+@end verbatim
+
+the compiler will quite appropriately complain that there is no conversion
+between these completely unrelated objects (CsmaChannel and Node).
+
+@subsection Summary
+Going back to our infamous first line of ns-3 code, we said that if
+we want to create an InternetNode in a script, we will typically do something
+like:
+
+@verbatim
+ Ptr<Node> p = CreateObject<InternetNode> ();
+@end verbatim
+
+@cindex Create
+@cindex InternetNode
+@cindex smart pointer
+Now we know that this is really a simple statement. We create an
+@code{InternetNode} object on the heap (indirecly using operator @code{new}
+and passing no parameters to its constructor) and assign responsibility for
+managing the new object's lifetime to a smart pointer. This smart pointer is
+a pointer to a @code{Node} object, so there was a hidden cast from
+@code{InternetNode} to a @code{Node} done via a standard C++ conversion.
+
+This may have been quite a hurdle to get past that first line of code, but
+we have covered quite a few of the important idioms that you'll encounter in
+this tutorial.
+
+@c ========================================================================
+@c A First ns-3 script
+@c ========================================================================
+
+@node A-First-ns-3-Script
+@chapter A First ns-3 script
+@cindex design pattern
+@cindex idiom
+Lets build a simple network using the ns-3 design patterns, idioms,
+classes and helpers we have just looked at. If you downloaded the system as
+was suggested above, you will have a release of ns-3 in a directory
+called @code{repos} under your home directory. Change into that directory,
+where you should see a directory structure something like the following.
+
+@verbatim
+ AUTHORS RELEASE_NOTES examples/ src/ waf*
+ LICENSE VERSION ns3/ tutorial/ waf.bat*
+ README doc/ samples/ utils/ wscript
+@end verbatim
+
+@cindex hello-simulator.cc
+Change into the tutorial directory. You should see a file named
+@code{hello-simulator.cc} located there. Copy this file into one named
+@code{simple.cc}. If you open this new file in your favorite editor you will
+see some copyright information and the following C++ code:
+
+@verbatim
+ #include "ns3/log.h"
+
+ NS_LOG_COMPONENT_DEFINE ("HelloSimulator");
+
+ using namespace ns3;
+
+ int
+ main (int argc, char *argv[])
+ {
+ LogComponentEnable ("HelloSimulator", LOG_LEVEL_INFO);
+
+ NS_LOG_INFO ("Hello Simulator");
+ }
+@end verbatim
+
+This is the ns-3 version of the ubiquitous hello-world program. It
+uses the ns-3 Log module to print ``Hello Simulator'' into the
+ standard error output stream.
+
+@cindex logging
+Log components are named objects that provide for controlling the verbosity of
+debugging output in the system. We'll have a lot more to say about logging
+later on, but for now you can just consider the macro @code{NS_LOG_INFO} to be
+a kind of fancy printf to the standard error.
+
+@section A Simple Network
+@cindex InternetNode
+Let's create a simple network of @code{InternetNode} elements. In order to
+actually create an @code{InternetNode}, you will have to include some header
+files. Put the following code after the include statement in @code{simple.cc}.
+
+@verbatim
+ #include "ns3/ptr.h"
+ #include "ns3/internet-stack.h"
+@end verbatim
+
+@cindex include files
+The ns-3 build system places the core include files it needs into a
+directory called @code{ns-3} and so whenever you need to include one of the
+core files you need to explicitly code this. The file @code{ptr.h} defines
+the generic smart pointer that we use. The file @code{internet-stack.h}
+defines the class InternetNode which, as described above, represents an IP
+version 4-based computing element in the simulator.
+
+So let's create a few new @code{InternetNode}s by adding the following lines
+of code after the call to @code{NS_LOG_INFO} in the simple.cc file right
+after the call to @code{NS_LOG_INFO}.
+
+@verbatim
+ Ptr<Node> n0 = CreateObject<InternetNode> ();
+ Ptr<Node> n1 = CreateObject<InternetNode> ();
+ Ptr<Node> n2 = CreateObject<InternetNode> ();
+ Ptr<Node> n3 = CreateObject<InternetNode> ();
+@end verbatim
+
+As we now understand, this will create four @code{InternetNode} objects on
+the heap and create four @code{Ptr<Node>} smart pointer objects on the stack
+to manage them. You should remember that by using the smart pointers you are
+freed from the responsibility to delete the objects you assign to them.
+
+@cindex Channel
+@cindex CsmaChannel
+The next step is to create a channel over which these nodes can communicate.
+Let's use the CsmaChannel and create a local area network that will allow us
+to hook up nodes similarly to an Ethernet.
+
+As usual, we'll need to include the file that provides the appropriate class
+declarations:
+
+@verbatim
+ #include "ns3/csma-channel.h"
+@end verbatim
+
+Next, Add the following line of code (typically done after node creation) to
+create a channel with a five megabit per second data rate and a two
+millisecond speed-of-light delay between all nodes. The idiom for creating
+the channel is similar to that of the node, but the actual @code{Create}
+function is hidden from us in the topology code. Observe that we are
+using a Csma topology helper function to free us from the details regarding
+how the Carrier Sense Multiple Access Channel is actually brought into
+existence and initialized.
+
+@verbatim
+ Ptr<CsmaChannel> lan =
+ CsmaTopology::CreateCsmaChannel (DataRate (5000000), MilliSeconds (2));
+@end verbatim
+
+@cindex idiom!unnamed parameter
+You may be unfamiliar with the @emph{unnamed parameter} idiom used here.
+When added to a list of parameters, the code @code{DataRate (5000000)}
+constructs a DataRate object on the stack using the appropriate constructor.
+The resulting object has no name, and therefore cannot be referenced
+elsewhere, but is passed to the callee method where it has a valid name and
+can be used. This idiom is essentially a shorthand version of the following:
+
+@verbatim
+ DataRate rate (5000000);
+ Time latency (MilliSeconds (2));
+ Ptr<CsmaChannel> lan = CsmaTopology::CreateCsmaChannel (rate, latency);
+@end verbatim
+
+@cindex constructor
+@cindex constructor!Time
+We should pause for a moment and discuss the constructor to the @code{Time}
+data type. There are a number of different constructors for these objects, and
+so there are a number of ways that this initialization could have been done.
+There is a constructor that takes a string argument, consisting of expressions
+using the units @code{s, ms, us, ns, ps} or @code{fs}, so this could have been
+written,
+
+@verbatim
+ Time latency ("2ms");
+@end verbatim
+
+There are also helper functions available that create time units (one of these
+was used in the example):
+
+@itemize @bullet
+@item @code{Seconds (double)}
+@item @code{MilliSeconds (uint64_t)}
+@item @code{MicroSeconds (uint64_t)}
+@item @code{NanoSeconds (uint64_t)}
+@item @code{PicoSeconds (uint64_t)}
+@item @code{FemtoSeconds (uint64_t)}
+@end itemize
+
+C++ will attempt to promote parameters appropriately, but you will typically
+see constructions that respect the type corrrectness of the constructor, as
+in @code{Seconds (1.)} and @code{MilliSeconds (2)}. Notice that the code
+@code{Seconds (1)} will work just as well as @code{Seconds (1.)} since the
+integer 1 will be automatically promoted to a double 1. in the former code.
+The converse will not work --- i.e., you cannot write code that says
+@code{MilliSeconds (2.)} since a @emph{type demotion} would be required that
+could lose information and the compiler will not do such things ``behind your
+back.'' Don't be thrown off by this kind of automatic conversion.
+
+@cindex MAC!address
+Okay, now we have code to create four nodes and a local area network. The
+next step is to wire the network together. We do this by adding net devices
+to the node. When we add the net device, we also specify the network to which
+the net device is connected and provide a MAC address appropriate to the
+device and network types. Since we're creating an IP version 4 network using
+a Csma channel, you may expect that we'll be using topology helpers
+appropriate to those types --- the CsmaIpv4Topology helper. As you may expect,
+we'll need to include some files to get the appropriate definitions:
+
+@verbatim
+ #include "ns3/mac48-address.h"
+ #include "ns3/csma-net-device.h"
+ #include "ns3/csma-topology.h"
+ #include "ns3/csma-ipv4-topology.h"
+@end verbatim
+
+Now, all that is left is to do the ``wiring'':
+
+@verbatim
+ uint32_t nd0 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n0, lan,
+ Mac48Address("08:00:2e:00:00:00"));
+@end verbatim
+
+[Note the additional unnamed parameter idiom usage here.]
+
+This code calls the topology helper relating to Csma channels and IP version
+four nodes. It asks to install a Csma net device ``into'' node zero
+(@code{n0}) connecting the device to the channel named (@code{lan}). It also
+assigns a MAC address to the net device. You can add similar lines of code
+connecting the other nodes to the lan (remembering to assign new MAC
+addresses).
+
+@verbatim
+ uint32_t nd1 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n1, lan,
+ Mac48Address("08:00:2e:00:00:01"));
+
+ uint32_t nd2 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n2, lan,
+ Mac48Address("08:00:2e:00:00:02"));
+
+ uint32_t nd3 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n3, lan,
+ Mac48Address("08:00:2e:00:00:03"));
+@end verbatim
+
+@cindex IP!address
+@cindex IP!network mask
+@cindex multihome
+Finally, we need to add IP addresses to our nodes. The pointers to the
+nodes are stored in n0, n1, n2 and n3. We added net devices to each of
+the nodes and remembered the net device index numbers as nd0, nd1, nd2 and
+nd3. You can add multiple net devices to each node resulting in a situation
+similar to a multi-homed host. Each time you add a net device, you will get
+a new index. Since the IP address for a multi-homed host is associated with
+a net device, we need to provide that index (which we have saved) to the
+topology helper. We provide an IP version four address via the ns-3
+class @code{Ipv4Address} which takes a dotted decimal string as a constructor
+parameter. We also provide a network mask using the ns-3 class
+@code{Ipv4Mask} which also takes a dotted decimal string. The code to
+perform the IP address assignment, then, looks like the following:
+
+@verbatim
+ CsmaIpv4Topology::AddIpv4Address (n0, nd0, Ipv4Address ("10.1.1.1"),
+ Ipv4Mask ("255.255.255.0"));
+
+ CsmaIpv4Topology::AddIpv4Address (n1, nd1, Ipv4Address ("10.1.1.2"),
+ Ipv4Mask ("255.255.255.0"));
+
+ CsmaIpv4Topology::AddIpv4Address (n2, nd2, Ipv4Address ("10.1.1.3"),
+ Ipv4Mask ("255.255.255.0"));
+
+ CsmaIpv4Topology::AddIpv4Address (n3, nd3, Ipv4Address ("10.1.1.4"),
+ Ipv4Mask ("255.255.255.0"));
+@end verbatim
+
+We have now constructed a simulated network. Your code should now look
+something like the following,
+
+@verbatim
+ #include "ns3/log.h"
+ #include "ns3/ptr.h"
+ #include "ns3/internet-stack.h"
+ #include "ns3/csma-channel.h"
+ #include "ns3/mac48-address.h"
+ #include "ns3/csma-net-device.h"
+ #include "ns3/csma-topology.h"
+ #include "ns3/csma-ipv4-topology.h"
+
+ NS_LOG_COMPONENT_DEFINE ("HelloSimulator");
+
+ using namespace ns3;
+
+ int
+ main (int argc, char *argv[])
+ {
+ LogComponentEnable ("HelloSimulator", LOG_LEVEL_INFO);
+
+ NS_LOG_INFO ("Hello Simulator");
+
+ Ptr<Node> n0 = CreateObject<InternetNode> ();
+ Ptr<Node> n1 = CreateObject<InternetNode> ();
+ Ptr<Node> n2 = CreateObject<InternetNode> ();
+ Ptr<Node> n3 = CreateObject<InternetNode> ();
+
+ Ptr<CsmaChannel> lan =
+ CsmaTopology::CreateCsmaChannel (DataRate (5000000), MilliSeconds (2));
+
+ uint32_t nd0 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n0, lan,
+ Mac48Address("08:00:2e:00:00:00"));
+
+ uint32_t nd1 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n1, lan,
+ Mac48Address("08:00:2e:00:00:01"));
+
+ uint32_t nd2 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n2, lan,
+ Mac48Address("08:00:2e:00:00:02"));
+
+ uint32_t nd3 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n3, lan,
+ Mac48Address("08:00:2e:00:00:03"));
+
+ CsmaIpv4Topology::AddIpv4Address (n0, nd0, Ipv4Address ("10.1.1.1"),
+ Ipv4Mask ("255.255.255.0"));
+
+ CsmaIpv4Topology::AddIpv4Address (n1, nd1, Ipv4Address ("10.1.1.2"),
+ Ipv4Mask ("255.255.255.0"));
+
+ CsmaIpv4Topology::AddIpv4Address (n2, nd2, Ipv4Address ("10.1.1.3"),
+ Ipv4Mask ("255.255.255.0"));
+
+ CsmaIpv4Topology::AddIpv4Address (n3, nd3, Ipv4Address ("10.1.1.4"),
+ Ipv4Mask ("255.255.255.0"));
+ }
+@end verbatim
+
+This script won't actually do anything yet. The next trick will be to
+convince our nodes to try and send some data over the network.
+
+@section Using Applications
+@cindex Create
+As mentioned above, we use @code{Application}s in ns-3 to generate
+the data used to drive simulations. An @code{Application} is added to a
+ns-3 node conceptually just as if you would add an application to a
+computer. When an application is created (using the @code{Create} template)
+we tell the application which @code{Node} it belongs to (and therefore on
+which node it is running) by passing a smart pointer to that @code{Node} in
+the constructor arguments.
+
+@subsection A UDP Echo Client Application
+To use an application, we first have to load the header file in which it is
+defined. For the UDP echo client, this would mean adding the line,
+
+@verbatim
+#include "ns3/udp-echo-client.h"
+@end verbatim
+
+In order to create the UDP echo client application we will need to add the
+following code:
+
+@verbatim
+ uint32_t packetSize = 1024;
+ uint16_t port = 7;
+ uint32_t maxPacketCount = 1;
+ Time interPacketInterval = Seconds (1.);
+
+ Ptr<UdpEchoClient> client = CreateObject<UdpEchoClient> (n0, "10.1.1.2",
+ port, maxPacketCount, interPacketInterval, packetSize);
+@end verbatim
+
+@cindex packet
+The first four lines have broken out the configuration parameters for the
+application as named parameters for clarity. We are telling the application
+to generate 1024 byte packets (@code{packetSize = 1024}); and to send these
+packets to port 7 (@code{port = 7;}). The application is told to send at most
+one packet (@code{maxPacketCount = 1;}); and to delay for one second between
+packet sends (@code{interpacketInterval = Seconds(1.)}) which is not used since
+only one packet is sent. We will defer addressing the type @code{Time} until
+we discuss the simulator engine. For now just understand the semantics are
+to wait for one second.
+
+The code to actually create the @code{UdpEchoClient} application uses the
+same creation idiom as we have used previously. Notice that we have a case
+where the @code{Create} template is used to pass parameters to the constructor
+of the underlying object.
+
+@cindex implicit conversion sequence
+Notice that a string is passed as the second parameter. The formal parameter
+to the constructor of the @code{UdpEchoClient} object is actually an
+@code{Ipv4Address}. We get away with this since C++ allows what are called
+@emph{implicit conversion sequences} to occur between the argument in the
+function call and the corresponding parameter in the function declaration.
+Basically, C++ will try to figure out a way to convert parameters for you
+transparently.
+
+In this case the conversion sequence is based on the constructor for the
+Ipv4Address that takes a @code{char const *} as a parameter. C++ notices
+that @code{"10.1.1.2"} refers to a @code{char const *} and knows that it
+needs to get from there to an @code{Ipv4Address}. The compiler notices that
+there is an @code{Ipv4Address} constructor that takes a @code{char const *}
+and so it uses that constructor transparently to arrange for the conversion.
+
+You therefore have several options for passing this value. You can use an
+explicit named variable as in the following:
+
+@verbatim
+ Ipv4Address addr ("10.1.1.2");
+ ...
+
+ Ptr<UdpEchoClient> client = CreateObject<UdpEchoClient> (n0, addr, port,
+ maxPacketCount, interPacketInterval, packetSize);
+@end verbatim
+
+@cindex idiom|unnamed parameter
+You can use the unnamed parameter idiom that we have previously seen:
+
+@verbatim
+ Ptr<UdpEchoClient> client = CreateObject<UdpEchoClient> (n0,
+ Ipv4Address ("10.1.1.2"), port, maxPacketCount, interPacketInterval,
+ packetSize);
+@end verbatim
+
+Or you can rely on implicit conversion sequences as we just saw:
+
+@verbatim
+ Ptr<UdpEchoClient> client = CreateObject<UdpEchoClient> (n0, "10.1.1.2",
+ port, maxPacketCount, interPacketInterval, packetSize);
+@end verbatim
+
+Which approach to take is a matter of style, really, and you will probably
+see all three approaches taken in the ns-3 code. You should be
+comfortable seeing and using all three methods.
+
+@subsection A UDP Echo Server Application
+As usual, to use the UDP echo server we need to add a line to define the
+application:
+
+@verbatim
+#include "ns3/udp-echo-server.h"
+@end verbatim
+
+In order to create the UDP echo server application we will need to add the
+following code:
+
+@verbatim
+ Ptr<UdpEchoServer> server = CreateObject<UdpEchoServer> (n1, port);
+@end verbatim
+
+We only need to tell the application which node to reside on and which port
+to listen on for UDP packets. The code to actually create the
+@code{UdpEchoServer} application uses the now quite familiar ns-3 object
+creation idiom.
+
+@subsection A UDP Echo Client-Server Simulation
+Now we're getting somewhere. Your code should look something like the
+following (let's change the log component name and program banner from
+``Hello Simulator''to something more descriptive while we're at it).
+
+@verbatim
+ #include "ns3/log.h"
+ #include "ns3/ptr.h"
+ #include "ns3/internet-stack.h"
+ #include "ns3/csma-channel.h"
+ #include "ns3/mac48-address.h"
+ #include "ns3/csma-net-device.h"
+ #include "ns3/csma-topology.h"
+ #include "ns3/csma-ipv4-topology.h"
+ #include "ns3/udp-echo-client.h"
+ #include "ns3/udp-echo-server.h"
+
+ NS_LOG_COMPONENT_DEFINE ("UdpEchoSimulation");
+
+ using namespace ns3;
+
+ int
+ main (int argc, char *argv[])
+ {
+ LogComponentEnable ("UdpEchoSimulation", LOG_LEVEL_INFO);
+
+ NS_LOG_INFO ("UDP Echo Simulation");
+
+ Ptr<Node> n0 = CreateObject<InternetNode> ();
+ Ptr<Node> n1 = CreateObject<InternetNode> ();
+ Ptr<Node> n2 = CreateObject<InternetNode> ();
+ Ptr<Node> n3 = CreateObject<InternetNode> ();
+
+ Ptr<CsmaChannel> lan =
+ CsmaTopology::CreateCsmaChannel (DataRate (5000000), MilliSeconds (2));
+
+ uint32_t nd0 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n0, lan,
+ Mac48Address("08:00:2e:00:00:00"));
+
+ uint32_t nd1 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n1, lan,
+ Mac48Address("08:00:2e:00:00:01"));
+
+ uint32_t nd2 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n2, lan,
+ Mac48Address("08:00:2e:00:00:02"));
+
+ uint32_t nd3 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n3, lan,
+ Mac48Address("08:00:2e:00:00:03"));
+
+ CsmaIpv4Topology::AddIpv4Address (n0, nd0, Ipv4Address ("10.1.1.1"),
+ Ipv4Mask ("255.255.255.0"));
+
+ CsmaIpv4Topology::AddIpv4Address (n1, nd1, Ipv4Address ("10.1.1.2"),
+ Ipv4Mask ("255.255.255.0"));
+
+ CsmaIpv4Topology::AddIpv4Address (n2, nd2, Ipv4Address ("10.1.1.3"),
+ Ipv4Mask ("255.255.255.0"));
+
+ CsmaIpv4Topology::AddIpv4Address (n3, nd3, Ipv4Address ("10.1.1.4"),
+ Ipv4Mask ("255.255.255.0"));
+
+ uint32_t packetSize = 1024;
+ uint16_t port = 7;
+ uint32_t maxPacketCount = 1;
+ Time interPacketInterval = Seconds (1.);
+
+ Ptr<UdpEchoClient> client = CreateObject<UdpEchoClient> (n0, "10.1.1.2",
+ port, maxPacketCount, interPacketInterval, packetSize);
+
+ Ptr<UdpEchoServer> server = CreateObject<UdpEchoServer> (n1, port);
+
+ }
+@end verbatim
+
+@section Using the Simulation Engine
+@cindex model
+@cindex simulation executive
+You could say that the heart of the ns-3 system is the
+@emph{simulation engine} (sometimes called the simulation executive in other
+systems).
+
+In a computer simulation, a computer @emph{model} of a real world @emph{system}
+is constructed. This is typically done to minimize cost since you do not have
+to actually buy, install and maintain physical hardware. In the case of
+ns-3, a model is a representation of a networking component that is
+designed to imitate some number of important behaviors or characteristics of
+an actual component in a real network. A system is a collection of models
+arranged for the purpose of analyzing some behavior.
+
+@section Models
+@cindex CsmaNetDevice
+@cindex CsmaChannel
+@cindex InternetNode
+@cindex NIC
+@cindex CSMA
+We have already encountered several ns-3 models without specifically
+calling them so. The @code{InternetNode}, @code{CsmaNetDevice} and
+@code{CsmaChannel} objects are models of an Internet computing node, a CSMA
+network interface card (NIC), and a network cable able to move data to and
+from other CSMA NICs.
+
+@cindex model
+@cindex CSMA/CD
+It is important to note that the @code{Csma} net devices and the @code{Csma}
+channel do not correspond to any real world hardware that you can actually go
+out and buy. These models implement an approximation, or subset, of the
+behaviors that a real CSMA/CD network would have. In this case, the
+@code{CsmaNetDevice} does not simulate collision detection (CD). It does
+implement carrier sense and performs collision @emph{avoidance} using global
+spatial knowledge available in the channel. This would be impossible in any
+channel residing in our universe.
+
+@cindex Ethernet
+No model will fully implement @emph{all} of the behaviors of a piece of
+hardware. It is important to understand what is being modeled by the
+ns-3 components you are using and what is not. For example, the Csma
+components we use in this tutorial model a highly abstract multiple access
+network that is topologically equivalent to an Ethernet. It is not necessarily
+true that results found in a simulation using the Csma models will apply to
+a real-world Ethernet network. You must understand what behaviors are
+simulated in each of the models before trusting that any results can be
+associated with real-world systems.
+
+@section Time, Events and Callbacks
+@cindex time
+@cindex event
+In a @emph{discrete event simulator} time is not something that @emph{flows},
+nor is it something to be measured --- it is the driving force behind the
+progress of the simulation. Time is progressed forward by the simulation
+engine and anything that happens in the simulation is ultimately caused by
+an @emph{event}. An event is some action in the system that is
+@emph{scheduled} to happen at a certain time by the simulation engine. Time
+does not flow continuously but steps discretely (in possibly large jumps)
+from one scheduled event to another.
+
+@cindex packet
+For example, to start the flow of a packet through the system, one would have
+to schedule an event with the simulation engine @emph{before} the simulation
+was started. This is important since the simulation engine only jumps time
+forward if there is a next event to process. The simulation stops if there
+are no more events, which is equivalent to a state where there is ``nothing
+more to do.'' Before the simulation starts, one schedules driving events in
+terms of absolute time. For example, one could schedule an event to start
+the flow of a first packet at, say, ten simulated seconds. In this case, the
+simulation would start its clock at zero seconds and look for the first event
+in its @emph{event queue}. It would immediately jump time forward by ten
+seconds and @emph{fire} the scheduled event --- that is, make the event happen.
+
+@cindex functor
+@cindex function object
+@cindex callback
+@cindex Callback
+In ns-3 an event is basically a pre-packaged function call called a
+@emph{functor}. Functors are also known as @emph{function objects}, which is
+a more descriptive term --- an object (in the object-oriented programming
+sense) that can be called as if it was a function. Typically one uses a
+functor to implement @emph{deferred execution} of a function or method. The
+most commonly encoutered form of deferred execution is in a @emph{callback}
+from an I/O system. In this case, the goal would be to start an I/O
+operation and return immediately, without having to wait for the operation
+to complete. One asks the I/O subsytem to notify you when an operation is
+complete by calling some function you provide. This provided function is
+known as a callback function. [Imagine calling someone on the telephone and
+asking them to do something for you. You also ask them to @emph{call you back}
+when they are done.] Events in the ns-3 system work conceptually
+the same way, except that instead of an I/O completion driving the process,
+the arrival of some simulated time drives the process. The ns-3
+deferred exectution mechanism is via a class called @code{Callback}.
+
+@cindex Time
+@cindex Callback
+The internal details of the classes representing @code{Time} and
+@code{Callback} abstractions will be introduced as required. We won't see
+events directly for some time, but you should know that they are happening
+``under the sheets'' of the simulations you will be writing.
+
+@section Driving the Simulation
+@cindex Application
+As mentioned previously, time is the driving force behind the progress of
+a ns-3 simulation. Events are scheduled to happen at certain times
+by calling methods of the simulation engine, either directly or indirectly
+through, for example, an @code{Application}.
+
+In order to get the simulation engine set up and running in our code, we must
+first include the language definitions required to describe time- and
+simulator-specific classes:
+
+@verbatim
+ #include "ns3/simulator.h"
+ #include "ns3/nstime.h"
+@end verbatim
+
+@cindex Application
+As we have seen, we need to ``seed'' the simulation with at least one event.
+In the case of an @code{Application}, a method to do this is provided. This
+method must be implemented by each specialization of the class and we must
+call this method in our script before the simulation starts. We can also
+provide an event (indirectly) to stop the output of the application at a
+certain time. This is done by adding the following lines to our script:
+
+@verbatim
+ server->Start(Seconds(1.));
+ client->Start(Seconds(2.));
+
+ server->Stop (Seconds(10.));
+ client->Stop (Seconds(10.));
+@end verbatim
+
+@cindex Application
+@cindex time
+@cindex Time
+@cindex socket
+@cindex event
+In the case of the UdpEchoServer, the call to @code{server->Start ()} gives
+the @code{Application} the chance to schedule an event that will perform the
+usual @emph{sockets} server sequence of socket creation, binding and
+recvfrom (see Donahoo's UDPEchoServer.c).
+
+In the case of the UdpEchoClient, the call to @code{client->Start ()} gives
+the @code{Application} the chance to schedule an event that will perform the
+usual @emph{sockets} client sequence of socket creation, sendto and recvfrom
+(see Donahoo's UDPEchoClient.c).
+
+@cindex event
+Note that the start event for the server is scheduled to happen before the
+start event of the client, just as you would start a server application before
+you would attempt to start a client application in the real world.
+
+@cindex socket!sendto
+The ns-3 equivalent of the call to @code{sendo} in the client will
+schedule (immediately) the transmission of a UDP packet over the just created
+socket. This will cause the packet to percolate down the protocol stack and
+eventually into the channel. The channel will schedule a reception event in
+the net device on the destination node. This event will eventually percolate
+up into the server application. The server application will create a reply
+packet and send it back down its stack and eventually back to the channel.
+The channel will schedule a reception event back in the client and this will
+cause the reply to be sent back up the protocol stack to the client
+application.
+
+The calls to @code{Stop ()} for both applications cause the sockets to be
+torn down and therefore the sending and receiving of packets will be stopped
+irrespective of other application settings (such as max packets and interval
+in the client).
+
+Finally, we need to run the simulation and when the simulation run is complete,
+clean up any resources allocated during the run. This is done by the calling
+the following static methods:
+
+@verbatim
+ Simulator::Run ();
+ Simulator::Destroy ();
+@end verbatim
+
+We now have the makings of a complete ns-3 network simulation. The
+source code for the script should look like the following:
+
+@verbatim
+ #include "ns3/log.h"
+ #include "ns3/ptr.h"
+ #include "ns3/internet-stack.h"
+ #include "ns3/csma-channel.h"
+ #include "ns3/mac48-address.h"
+ #include "ns3/csma-net-device.h"
+ #include "ns3/csma-topology.h"
+ #include "ns3/csma-topology.h"
+ #include "ns3/csma-ipv4-topology.h"
+ #include "ns3/udp-echo-client.h"
+ #include "ns3/udp-echo-server.h"
+ #include "ns3/simulator.h"
+ #include "ns3/nstime.h"
+
+ NS_LOG_COMPONENT_DEFINE ("UdpEchoSimulation");
+
+ using namespace ns3;
+
+ int
+ main (int argc, char *argv[])
+ {
+ LogComponentEnable ("UdpEchoSimulation", LOG_LEVEL_INFO);
+
+ NS_LOG_INFO ("UDP Echo Simulation");
+
+ Ptr<Node> n0 = CreateObject<InternetNode> ();
+ Ptr<Node> n1 = CreateObject<InternetNode> ();
+ Ptr<Node> n2 = CreateObject<InternetNode> ();
+ Ptr<Node> n3 = CreateObject<InternetNode> ();
+
+ Ptr<CsmaChannel> lan =
+ CsmaTopology::CreateCsmaChannel (DataRate (5000000), MilliSeconds (2));
+
+ uint32_t nd0 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n0, lan,
+ Mac48Address("08:00:2e:00:00:00"));
+
+ uint32_t nd1 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n1, lan,
+ Mac48Address("08:00:2e:00:00:01"));
+
+ uint32_t nd2 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n2, lan,
+ Mac48Address("08:00:2e:00:00:02"));
+
+ uint32_t nd3 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n3, lan,
+ Mac48Address("08:00:2e:00:00:03"));
+
+ CsmaIpv4Topology::AddIpv4Address (n0, nd0, Ipv4Address ("10.1.1.1"),
+ Ipv4Mask ("255.255.255.0"));
+
+ CsmaIpv4Topology::AddIpv4Address (n1, nd1, Ipv4Address ("10.1.1.2"),
+ Ipv4Mask ("255.255.255.0"));
+
+ CsmaIpv4Topology::AddIpv4Address (n2, nd2, Ipv4Address ("10.1.1.3"),
+ Ipv4Mask ("255.255.255.0"));
+
+ CsmaIpv4Topology::AddIpv4Address (n3, nd3, Ipv4Address ("10.1.1.4"),
+ Ipv4Mask ("255.255.255.0"));
+
+ uint32_t packetSize = 1024;
+ uint16_t port = 7;
+ uint32_t maxPacketCount = 1;
+ Time interPacketInterval = Seconds (1.);
+
+ Ptr<UdpEchoClient> client = CreateObject<UdpEchoClient> (n0, "10.1.1.2",
+ port, maxPacketCount, interPacketInterval, packetSize);
+
+ Ptr<UdpEchoServer> server = CreateObject<UdpEchoServer> (n1, port);
+
+ server->Start(Seconds(1.));
+ client->Start(Seconds(2.));
+
+ server->Stop (Seconds(10.));
+ client->Stop (Seconds(10.));
+
+ Simulator::Run ();
+ Simulator::Destroy ();
+ }
+@end verbatim
+
+@cindex tutorial-csma-echo.cc
+Just to make sure you don't get caught up in debugging typographical errors
+we have provided this source code for you (along with a copyright header) in
+the @code{tutorial} subdirectory of the ns-3 distribution as
+@code{tutorial-csma-echo.cc}. We used this opportunity to do some ``clean up''
+of some of our example cases by passing parameters using implicit conversion
+sequences and removing some of the named parameters. [These were used for
+pedagogic purposes and were not actually necessary.]
+
+@section Building the Script
+@cindex Waf
+C++ is a compiled language, so you know it had to happen. We have to build
+the script before we run it. As mentioned before, we use the Waf build system
+which is Python-based. We have to change gears slightly and switch ourselves
+to Python mode in order to proceed.
+
+In each subdirectory of the ns-3 distribution in which there are
+source files, you will find two files: one will be named @code{waf} and one
+will be named @code{wscript}. The former, @code{waf}, is a link that allows
+one to start the build process from any subdirectory. We can ignore that one.
+The file we need to deal with is @code{wscript}.
+
+@cindex wscript
+Open the file @code{ns-3-dev/tutorial/wscript} in your favorite editor
+[remember I'm assuming that you have the distribution saved in a
+repository under a directory called @code{repos} in you home directory.]
+
+@cindex Python
+You should see the following Python code (after an emacs mode line).
+
+@verbatim
+ def build(bld):
+ obj = bld.create_ns3_program('hello-simulator')
+ obj.source = 'hello-simulator.cc'
+@end verbatim
+
+These are the only instructions required to build a simulation (I told you
+it wasn't going to be too bad). The line with the method
+@code{bld.create_ns3_program} tells the build system to create an object
+file that is a program (executable) named @code{hello-simulator}. The
+following line, with the method @code{obj.source} tells the build system that
+the source file for the program is the file @code{hello-simulator.cc'} in the
+local directory. The required libraries are linked for you for free.
+
+All that needed to be done in order to build the new simulation using the new
+source file was to copy the two lines describing the @code{hello-simulator}
+program and change the names to @code{tutorial-csma-echo}. You can see these
+lines in the @code{wscript} file,
+
+@verbatim
+ def build(bld):
+ obj = bld.create_ns3_program('hello-simulator')
+ obj.source = 'hello-simulator.cc'
+
+ obj = bld.create_ns3_program('tutorial-csma-echo')
+ obj.source = 'tutorial-csma-echo.cc'
+
+ ...
+@end verbatim
+
+When you built the system above, you actually already built this new
+simulation and a number of other examples. Since you have already configured
+@code{Waf} and built the @code{tutorial-csma-echo} script, you can run the
+simulation in the same way as you ran the @code{hello-simulator} script using
+the @code{waf --run} command:
+
+@verbatim
+~/repos/ns-3-dev/tutorial > waf --run tutorial-csma-echo
+Entering directory `~/repos/ns-3-dev/build'
+Compilation finished successfully
+UDP Echo Simulation
+~/repos/ns-3-dev/tutorial >
+@end verbatim
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/tutorial/in-process/log.texi Sat Jun 28 19:46:55 2008 -0700
@@ -0,0 +1,24 @@
+@node Logging
+@chapter Logging
+@anchor{chap:Logging}
+
+This chapter is the first in a series of chapters discussing things that
+one can do to modify the input or output of existing ns-3 scripts.
+
+Examples:
+@itemize @bullet
+@item Enable or disable the generation of log messages, with fine granularity
+@item Set default values for configuration values in the system
+@item Generate a report of all configuration values used during a simulation
+run (not yet implemented)
+@item Set or get values of member variables on objects already instantiated
+@item Customizing the tracing output of the script
+@item Generate statistics on (not yet implemented)
+@item Perform a large number of independent runs of the same simulation
+@end itemize
+
+@node Logging Basics
+@section Logging Basics
+
+@node Enabling Log Output
+@section Enabling Log Output
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/tutorial/in-process/other.texi Sat Jun 28 19:46:55 2008 -0700
@@ -0,0 +1,2189 @@
+@c ========================================================================
+@c Other Network Topologies
+@c ========================================================================
+
+@node Other-network-topologies
+@chapter Other Network Topologies
+@cindex topology
+@cindex Channel
+@cindex NetDevice
+@cindex topology!bus
+@cindex topology!point-to-point
+@cindex PointToPointChannel
+@cindex PointToPointNetDevice
+
+@emph{Network topology} is the study of the arrangement of of the elements
+(in @command{ns-3} represented by the classes @code{Channel} and @code{Node})
+of a network. Two fundamental types of physical topologies are the
+@emph{point-to-point} and @emph{bus} topologies. We have already been exposed
+to the @command{ns-3} channel specialization named @code{CsmaChannel}. This is
+a simulation of a bus network. We also provide a simulation of a
+point-to-point channel with associated net devices. As described previously,
+the associated C++ classes specialize the @command{ns-3} base classes
+@code{NetDevice} and @code{Channel} and are called @code{PointToPointNetDevice}
+and @code{PointToPointChannel} respectively.
+
+We will use combinations of these bus and point-to-point topology elements
+to show how to create several commonly seen network topologies.
+
+@section A Point-to-Point Network
+We're going to take what might be seen as a step backward and look at a simple
+point-to-point network. We will be building the simplest network you can
+imagine. A serial link (point to point) between two computers. When you
+see this point-to-point network, you can think of an RS-422 (or RS-232 for
+you old-timers) cable. This topology is shown below.
+
+@sp 1
+@center @image{figures/pp,,,,png}
+
+@cindex CreateObject
+@cindex InternetNode
+We have provided a file for you in the @code{tutorial}
+directory called @code{tutorial-point-to-point.cc}. You should now be
+familiar enough with the system to pick out fairly easily what has been
+changed. Let's focus on the following lines:
+
+@verbatim
+ Ptr<Node> n0 = CreateObject<InternetNode> ();
+ Ptr<Node> n1 = CreateObject<InternetNode> ();
+
+ Ptr<PointToPointChannel> link = PointToPointTopology::AddPointToPointLink (
+ n0, n1, DataRate (38400), MilliSeconds (20));
+
+ PointToPointTopology::AddIpv4Addresses (link, n0, "10.1.1.1",
+ n1, "10.1.1.2");
+@end verbatim
+
+You can see that we created two @code{InternetNode} objects in the usual way.
+Then, instead of creating a @code{CsmaChannel} we create a
+@code{PointToPointChannel}. This point-to-point channel, which we call
+@code{link}, connects node zero (@code{n0}) and node one (@code{n1}) over a
+simulated link that runs at 38400 bits per second and has a 20 millisecond
+simulated speed-of-light delay. This call also creates appropriate net devices
+and attaches them to nodes zero and one.
+
+We then add IP addresses to the net devices we just created using the topology
+helper @code{AddIpv4Addresses}. Node zero gets the IP address 10.1.1.1 and
+node one gets the IP address 10.1.1.2 assigned.
+
+The alert tutorial user may wonder what the network number or prefix is of
+those IP addresses. The point-to-point topology assumes that you want a
+@code{/30} subnet and assigns an appropriate net mask for you. It then then
+@emph{asserts} that the network numbers of the two net devices match. So there
+is an implicit network mask created down in the topology code that looks like,
+
+@verbatim
+ Ipv4Mask netmask("255.255.255.252");
+@end verbatim
+
+The rest of the code you should recognize and understand. We are just going
+to echo one packet across the point-to-point link. You should be now be able
+to build and run this example and to locate and interpret the ASCII trace
+file. This is left as an exercise for you.
+
+The file @code{tutorial-point-to-point.cc} is reproduced here for your
+convenience:
+
+@verbatim
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ns3/log.h"
+#include "ns3/ptr.h"
+#include "ns3/internet-stack.h"
+#include "ns3/point-to-point-channel.h"
+#include "ns3/mac48-address.h"
+#include "ns3/point-to-point-net-device.h"
+#include "ns3/point-to-point-topology.h"
+#include "ns3/udp-echo-client.h"
+#include "ns3/udp-echo-server.h"
+#include "ns3/simulator.h"
+#include "ns3/nstime.h"
+#include "ns3/ascii-trace.h"
+#include "ns3/pcap-trace.h"
+#include "ns3/global-route-manager.h"
+
+NS_LOG_COMPONENT_DEFINE ("PointToPointSimulation");
+
+using namespace ns3;
+
+// Network topology
+//
+// point to point
+// +--------------+
+// | |
+// n0 n1
+//
+int
+main (int argc, char *argv[])
+{
+ LogComponentEnable ("PointToPointSimulation", LOG_LEVEL_INFO);
+
+ NS_LOG_INFO ("Point to Point Topology Simulation");
+
+ Ptr<Node> n0 = CreateObject<InternetNode> ();
+ Ptr<Node> n1 = CreateObject<InternetNode> ();
+
+ Ptr<PointToPointChannel> link = PointToPointTopology::AddPointToPointLink (
+ n0, n1, DataRate (38400), MilliSeconds (20));
+
+ PointToPointTopology::AddIpv4Addresses (link, n0, "10.1.1.1",
+ n1, "10.1.1.2");
+
+ uint16_t port = 7;
+
+ Ptr<UdpEchoClient> client = CreateObject<UdpEchoClient> (n0, "10.1.1.2",
+ port, 1, Seconds(1.), 1024);
+
+ Ptr<UdpEchoServer> server = CreateObject<UdpEchoServer> (n1, port);
+
+ server->Start(Seconds(1.));
+ client->Start(Seconds(2.));
+
+ server->Stop (Seconds(10.));
+ client->Stop (Seconds(10.));
+
+ AsciiTrace asciitrace ("tutorial.tr");
+ asciitrace.TraceAllQueues ();
+ asciitrace.TraceAllNetDeviceRx ();
+
+ Simulator::Run ();
+ Simulator::Destroy ();
+}
+@end verbatim
+
+@section A Star Network
+A point-to-point network is considered a special case of a star network. As
+you might expect, the process of constructing a star network is an extension
+of the very simple process used for a point-to-point link. We have provided
+a file for you in the @code{tutorial} directory called @code{tutorial-star.cc}
+that implements a simple star network as seen below.
+
+@sp 1
+@center @image{figures/star,,,,png}
+
+In order to create a star network, we need to be able to instantiate some
+number (greater than one) of net devices on a node. In the name of simplicity
+of use, the @code{PointToPointTopology} topology helper does not allow one to
+do this. We provided a separate topology helper class, the
+@code{PointToPointIpv4Topology} helper class that provides the slightly finer
+granularity we need to accomplish a star network. In order to use this new
+helper we have to load the definitions by including the appropriate file.
+
+@verbatim
+ #include "ns3/point-to-point-ipv4-topology.h"
+@end verbatim
+
+The star that we're going to create has a node in the center (@code{n0}) with
+six nodes surrounding (@code{n1} - @code{n6}). You should be able to easily
+find and understand the code that creates these nodes.
+
+@verbatim
+ Ptr<Node> n0 = CreateObject<InternetNode> ();
+ Ptr<Node> n1 = CreateObject<InternetNode> ();
+ Ptr<Node> n2 = CreateObject<InternetNode> ();
+ Ptr<Node> n3 = CreateObject<InternetNode> ();
+ Ptr<Node> n4 = CreateObject<InternetNode> ();
+ Ptr<Node> n5 = CreateObject<InternetNode> ();
+ Ptr<Node> n6 = CreateObject<InternetNode> ();
+@end verbatim
+
+Next, we get into the differences between the @code{PointToPointTopology}
+helper and the @code{PointToPointIpv4Topology} helper. The
+@code{PointToPointIpv4Topology} helper looks and feels a little like the
+@code{CsmaIpv4Topology} helper. Just like you created a CSMA channel
+previously, you need to create a point-to-point channel. The following
+code creates a @code{PointToPointChannel} and calls it @code{link01}. You can
+interpret this name as being the channel (or @emph{link}) from node zero to
+node one.
+
+@verbatim
+ Ptr<PointToPointChannel> link01 =
+ PointToPointIpv4Topology::CreateChannel (DataRate (38400),
+ MilliSeconds (20));
+@end verbatim
+
+You need to provide a data rate for the channel which we set at 38400 bits
+per second. You must also provide a speed-of-light delay which we set at
+20 milliseconds.
+
+Just as you added a net device to the nodes in the CSMA tutorial section, you
+do the same here but with a point-to-point net device. The following code
+illustrates how we do that:
+
+@verbatim
+ uint32_t nd01 = PointToPointIpv4Topology::AddNetDevice (n0,
+ link01);
+@end verbatim
+
+We call the @code{PointToPointIpv4Topology} helper and ask it to add a net
+device to node zero (@code{n0}) and connect it to the appropriate
+point-to-point link (@code{link01}) which you will recall is the serial link
+from node zero to node one.
+
+If you look at the following code, you will see the same calls are repeated
+to create the remaining five point-to-point channels and connect them
+to net devices on node zero.
+
+The next new code is found after the ``spokes'' of the star have been created.
+It looks like the following:
+
+@verbatim
+ uint32_t nd1 = PointToPointIpv4Topology::AddNetDevice (n1, link01);
+ uint32_t nd2 = PointToPointIpv4Topology::AddNetDevice (n2, link02);
+ uint32_t nd3 = PointToPointIpv4Topology::AddNetDevice (n3, link03);
+ uint32_t nd4 = PointToPointIpv4Topology::AddNetDevice (n4, link04);
+ uint32_t nd5 = PointToPointIpv4Topology::AddNetDevice (n5, link05);
+ uint32_t nd6 = PointToPointIpv4Topology::AddNetDevice (n6, link06);
+@end verbatim
+
+Here we are creating the net devices on the nodes surrounding the center node.
+In the first call, we are adding a net device on node one (@code{n1}) and
+connecting that net device to the channel named @code{link01}. Remember that
+we created the channel @code{link01} as the channel connecting node zero and
+node one. We previously created a net device on node zero and attached that
+device to @code{link01}. Here we are connecting the other side of that link
+to node one. The return value from this call is the net device index of the
+created net device.
+
+The next section of code adds addresses to the net devices we just created.
+The first call adds the IP address 10.1.1.1 to the net device going from
+node zero to node one. Recall that we first created a node named @code{n0}
+and a channel called @code{link01}. We added a net device to @code{n0} and
+remembered the net device index as the @code{uint32_t nd01}. This meant
+the net device @emph{nd} on node @emph{0} that we connected to node @emph{1}.
+We call @code{AddAddress} to add an IP address (10.1.1.1) to the net device
+on node zero identified by the net device index @code{nd01}. We provide a
+net mask suitable for a point to point network. This is typically a /30
+address but we don't force that in this API.
+
+After setting up the address on node zero, we do the same for the node on
+the other end of the ``spoke'' --- in this case node one, with its single
+net device. Note that the network number is the same on both sides of this
+network.
+
+@verbatim
+ PointToPointIpv4Topology::AddAddress (n0, nd01, "10.1.1.1",
+ ``255.255.255.252'');
+
+ PointToPointIpv4Topology::AddAddress (n1, nd1, "10.1.1.2",
+ ``255.255.255.252'');
+@end verbatim
+
+The following code repeats this pattern assining similar IP addresses to the
+remaining net devices. Note that there are no @code{Mac48Address} address
+assignments --- they are not required.
+
+The rest of the code you should recognize and understand. We are just going
+to echo one packet across the point-to-point link. You should be now be able
+to build and run this example and to locate and interpret the ASCII trace
+file. This is left as an exercise for you.
+
+The file @code{tutorial-star.cc} is reproduced here for your convenience:
+
+@verbatim
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ns3/log.h"
+#include "ns3/ptr.h"
+#include "ns3/internet-stack.h"
+#include "ns3/point-to-point-channel.h"
+#include "ns3/mac48-address.h"
+#include "ns3/point-to-point-net-device.h"
+#include "ns3/point-to-point-ipv4-topology.h"
+#include "ns3/udp-echo-client.h"
+#include "ns3/udp-echo-server.h"
+#include "ns3/simulator.h"
+#include "ns3/nstime.h"
+#include "ns3/ascii-trace.h"
+#include "ns3/pcap-trace.h"
+#include "ns3/global-route-manager.h"
+
+NS_LOG_COMPONENT_DEFINE ("StarSimulation");
+
+using namespace ns3;
+
+// Network topology
+//
+// n3 n2
+// | /
+// | /
+// n4 --- n0 --- n1
+// / |
+// / |
+// n5 n6
+
+int
+main (int argc, char *argv[])
+{
+ LogComponentEnable ("StarSimulation", LOG_LEVEL_INFO);
+
+ NS_LOG_INFO ("Star Topology Simulation");
+
+ Ptr<Node> n0 = CreateObject<InternetNode> ();
+ Ptr<Node> n1 = CreateObject<InternetNode> ();
+ Ptr<Node> n2 = CreateObject<InternetNode> ();
+ Ptr<Node> n3 = CreateObject<InternetNode> ();
+ Ptr<Node> n4 = CreateObject<InternetNode> ();
+ Ptr<Node> n5 = CreateObject<InternetNode> ();
+ Ptr<Node> n6 = CreateObject<InternetNode> ();
+
+ Ptr<PointToPointChannel> link01 =
+ PointToPointIpv4Topology::CreateChannel (DataRate (38400),
+ MilliSeconds (20));
+
+ uint32_t nd01 = PointToPointIpv4Topology::AddNetDevice (n0,
+ link01);
+
+ Ptr<PointToPointChannel> link02 =
+ PointToPointIpv4Topology::CreateChannel (DataRate (38400),
+ MilliSeconds (20));
+
+ uint32_t nd02 = PointToPointIpv4Topology::AddNetDevice (n0,
+ link02);
+
+ Ptr<PointToPointChannel> link03 =
+ PointToPointIpv4Topology::CreateChannel (DataRate (38400),
+ MilliSeconds (20));
+
+ uint32_t nd03 = PointToPointIpv4Topology::AddNetDevice (n0,
+ link03);
+
+ Ptr<PointToPointChannel> link04 =
+ PointToPointIpv4Topology::CreateChannel (DataRate (38400),
+ MilliSeconds (20));
+
+ uint32_t nd04 = PointToPointIpv4Topology::AddNetDevice (n0,
+ link04);
+
+ Ptr<PointToPointChannel> link05 =
+ PointToPointIpv4Topology::CreateChannel (DataRate (38400),
+ MilliSeconds (20));
+
+ uint32_t nd05 = PointToPointIpv4Topology::AddNetDevice (n0,
+ link05);
+
+ Ptr<PointToPointChannel> link06 =
+ PointToPointIpv4Topology::CreateChannel (DataRate (38400),
+ MilliSeconds (20));
+
+ uint32_t nd06 = PointToPointIpv4Topology::AddNetDevice (n0, link06);
+
+ uint32_t nd1 = PointToPointIpv4Topology::AddNetDevice (n1, link01);
+ uint32_t nd2 = PointToPointIpv4Topology::AddNetDevice (n2, link02);
+ uint32_t nd3 = PointToPointIpv4Topology::AddNetDevice (n3, link03);
+ uint32_t nd4 = PointToPointIpv4Topology::AddNetDevice (n4, link04);
+ uint32_t nd5 = PointToPointIpv4Topology::AddNetDevice (n5, link05);
+ uint32_t nd6 = PointToPointIpv4Topology::AddNetDevice (n6, link06);
+
+ PointToPointIpv4Topology::AddAddress (n0, nd01, "10.1.1.1",
+ "255.255.255.252");
+
+ PointToPointIpv4Topology::AddAddress (n1, nd1, "10.1.1.2",
+ "255.255.255.252");
+
+ PointToPointIpv4Topology::AddAddress (n0, nd02, "10.1.2.1",
+ "255.255.255.252");
+
+ PointToPointIpv4Topology::AddAddress (n2, nd2, "10.1.2.2",
+ "255.255.255.252");
+
+ PointToPointIpv4Topology::AddAddress (n0, nd03, "10.1.3.1",
+ "255.255.255.252");
+
+ PointToPointIpv4Topology::AddAddress (n3, nd3, "10.1.2.2",
+ "255.255.255.252");
+
+ PointToPointIpv4Topology::AddAddress (n0, nd04, "10.1.4.1",
+ "255.255.255.252");
+
+ PointToPointIpv4Topology::AddAddress (n4, nd4, "10.1.4.2",
+ "255.255.255.252");
+
+ PointToPointIpv4Topology::AddAddress (n0, nd05, "10.1.5.1",
+ "255.255.255.252");
+
+ PointToPointIpv4Topology::AddAddress (n5, nd5, "10.1.5.2",
+ "255.255.255.252");
+
+ PointToPointIpv4Topology::AddAddress (n0, nd06, "10.1.6.1",
+ "255.255.255.252");
+
+ PointToPointIpv4Topology::AddAddress (n6, nd6, "10.1.6.2",
+ "255.255.255.252");
+
+ uint16_t port = 7;
+
+ Ptr<UdpEchoClient> client = CreateObject<UdpEchoClient> (n0, "10.1.1.2",
+ port, 1, Seconds(1.), 1024);
+
+ Ptr<UdpEchoServer> server = CreateObject<UdpEchoServer> (n1, port);
+
+ server->Start(Seconds(1.));
+ client->Start(Seconds(2.));
+
+ server->Stop (Seconds(10.));
+ client->Stop (Seconds(10.));
+
+ AsciiTrace asciitrace ("tutorial.tr");
+ asciitrace.TraceAllQueues ();
+ asciitrace.TraceAllNetDeviceRx ();
+
+ Simulator::Run ();
+ Simulator::Destroy ();
+}
+@end verbatim
+
+@subsection Routing
+If you are really excited about this simulator you may have already tried to
+modify the scripts outside the tutorial. I know that one of the first things
+that would have occurred to me when I saw the star network would have been to
+start trying to add applications to echo packets from nodes other than zero.
+If you tried, for example, to start the echo client on node one instead of
+node zero, you would have found an empty trace file. The reason for this
+is that you have now created an internetwork. This means you will need to
+enable internetwork routing.
+
+We have provided a file for you in the @code{tutorial} directory called
+@code{tutorial-star-routing.cc} to show you how this is done. This extremely
+tricky and difficult change is shown below:
+
+@verbatim
+ GlobalRouteManager::PopulateRoutingTables ();
+@end verbatim
+
+This one-line addition, located just before the simulation runs, tells the
+@command{ns-3} @emph{global route manager} to walk the topology you created and
+build internetwork routing tables for all of the nodes in the simulation.
+We changed the client application so that it runs on node four:
+
+@verbatim
+ Ptr<UdpEchoClient> client = CreateObject<UdpEchoClient> (n4, "10.1.1.2",
+ port, 1, Seconds(1.), 1024);
+@end verbatim
+
+Now if you build and run @code{tutorial-star-routing.cc} you can examine the
+@code{tutorial.tr} file and see that your UDP echo packets are now correctly
+routed through the topology.
+
+@section A Dumbbell Network
+One of the most interesting simple topologies (from a phenomenological point of
+view) is commonly called a dumbbell network. The name derives from a
+superficial similarity in form to a piece of exercise equipment.
+
+The dumbbell model is typically composed of two bus or star network elements
+connected via a point-to-point link. The point-to-point link is usually
+configured with a lower bandwidth than the bus elements to provide a
+@emph{choke point}.
+
+The following is a representation of the topology.
+
+@sp 1
+@center @image{figures/dumbbell,,,,png}
+
+We have provided a file that constructs this dumbbell network and creates
+enough data flowing across the choke point that some packets will be dropped.
+The file is called @code{tutorial-linear-dumbbell.cc} and is located in the
+@code{tutorial} directory. We have already covered all of the code used to
+create this network, so we will just quickly go over the main sections of the
+script.
+
+The first section creates a CSMA lan that will become the left side of the
+dumbbell network. This code should be very familiar since we used the same
+process to create our first example.
+
+@verbatim
+//
+// Create the lan on the left side of the dumbbell.
+//
+ Ptr<Node> n0 = CreateObject<InternetNode> ();
+ Ptr<Node> n1 = CreateObject<InternetNode> ();
+ Ptr<Node> n2 = CreateObject<InternetNode> ();
+ Ptr<Node> n3 = CreateObject<InternetNode> ();
+
+ Ptr<CsmaChannel> lan1 =
+ CsmaTopology::CreateCsmaChannel (DataRate (10000000), MilliSeconds (2));
+
+ uint32_t nd0 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n0, lan1,
+ "08:00:2e:00:00:00");
+
+ uint32_t nd1 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n1, lan1,
+ "08:00:2e:00:00:01");
+
+ uint32_t nd2 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n2, lan1,
+ "08:00:2e:00:00:02");
+
+ uint32_t nd3 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n3, lan1,
+ "08:00:2e:00:00:03");
+
+ CsmaIpv4Topology::AddIpv4Address (n0, nd0, "10.1.1.1", "255.255.255.0");
+ CsmaIpv4Topology::AddIpv4Address (n1, nd1, "10.1.1.2", "255.255.255.0");
+ CsmaIpv4Topology::AddIpv4Address (n2, nd2, "10.1.1.3", "255.255.255.0");
+ CsmaIpv4Topology::AddIpv4Address (n3, nd3, "10.1.1.4", "255.255.255.0");
+@end verbatim
+
+The code to generate the CSMA lan on the right side is similar; only the names
+have been changed.
+
+@verbatim
+//
+// Create the lan on the right side of the dumbbell.
+//
+ Ptr<Node> n4 = CreateObject<InternetNode> ();
+ Ptr<Node> n5 = CreateObject<InternetNode> ();
+ Ptr<Node> n6 = CreateObject<InternetNode> ();
+ Ptr<Node> n7 = CreateObject<InternetNode> ();
+
+ Ptr<CsmaChannel> lan2 =
+ CsmaTopology::CreateCsmaChannel (DataRate (10000000), MilliSeconds (2));
+
+ uint32_t nd4 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n4, lan2,
+ "08:00:2e:00:00:04");
+
+ uint32_t nd5 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n5, lan2,
+ "08:00:2e:00:00:05");
+
+ uint32_t nd6 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n6, lan2,
+ "08:00:2e:00:00:06");
+
+ uint32_t nd7 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n7, lan2,
+ "08:00:2e:00:00:07");
+
+ CsmaIpv4Topology::AddIpv4Address (n4, nd4, "10.1.2.1", "255.255.255.0");
+ CsmaIpv4Topology::AddIpv4Address (n5, nd5, "10.1.2.2", "255.255.255.0");
+ CsmaIpv4Topology::AddIpv4Address (n6, nd6, "10.1.2.3", "255.255.255.0");
+ CsmaIpv4Topology::AddIpv4Address (n7, nd7, "10.1.2.4", "255.255.255.0");
+@end verbatim
+
+Next, we create a point to point link to connect the two lans. We connect
+the point-to-point channel between nodes three (on the left lan) and four
+(on the right lan). You should recoginze this as substantially similar to
+the link setup from the @code{point-to-point} example.
+
+@verbatim
+//
+// Create the point-to-point link to connect the two lans.
+//
+ Ptr<PointToPointChannel> link = PointToPointTopology::AddPointToPointLink (
+ n3, n4, DataRate (38400), MilliSeconds (20));
+
+ PointToPointTopology::AddIpv4Addresses (link, n3, "10.1.3.1",
+ n4, "10.1.3.2");
+@end verbatim
+
+Then we configure data flows. We create four echo clients that send UDP
+packets from the left side lan to servers created on the right side lan.
+Notice that we send 100 packets with an inter-packet gap of ten milliseconds
+instead of the single packet we have previously used. This data rate is
+sufficient to saturate the point-to-point link and will cause packets to be
+dropped when the queue on the link net devices overflows (the default maximum
+queue depth is 100 packets). Note that we stagger the start of the echo
+clients to slowly bring up the data rates.
+
+@verbatim
+//
+// Create data flows across the link:
+// n0 ==> n4 ==> n0
+// n1 ==> n5 ==> n1
+// n2 ==> n6 ==> n2
+// n3 ==> n7 ==> n3
+//
+ uint16_t port = 7;
+
+ Ptr<UdpEchoClient> client0 = CreateObject<UdpEchoClient> (n0, "10.1.2.1",
+ port, 100, Seconds(.01), 1024);
+ Ptr<UdpEchoClient> client1 = CreateObject<UdpEchoClient> (n1, "10.1.2.2",
+ port, 100, Seconds(.01), 1024);
+ Ptr<UdpEchoClient> client2 = CreateObject<UdpEchoClient> (n2, "10.1.2.3",
+ port, 100, Seconds(.01), 1024);
+ Ptr<UdpEchoClient> client3 = CreateObject<UdpEchoClient> (n3, "10.1.2.4",
+ port, 100, Seconds(.01), 1024);
+
+ Ptr<UdpEchoServer> server4 = CreateObject<UdpEchoServer> (n4, port);
+ Ptr<UdpEchoServer> server5 = CreateObject<UdpEchoServer> (n5, port);
+ Ptr<UdpEchoServer> server6 = CreateObject<UdpEchoServer> (n6, port);
+ Ptr<UdpEchoServer> server7 = CreateObject<UdpEchoServer> (n7, port);
+
+ server4->Start(Seconds(1.));
+ server5->Start(Seconds(1.));
+ server6->Start(Seconds(1.));
+ server7->Start(Seconds(1.));
+
+ client0->Start(Seconds(2.));
+ client1->Start(Seconds(2.1));
+ client2->Start(Seconds(2.2));
+ client3->Start(Seconds(2.3));
+
+ server4->Stop (Seconds(10.));
+ server5->Stop (Seconds(10.));
+ server6->Stop (Seconds(10.));
+ server7->Stop (Seconds(10.));
+
+ client0->Stop (Seconds(10.));
+ client1->Stop (Seconds(10.));
+ client2->Stop (Seconds(10.));
+ client3->Stop (Seconds(10.));
+@end verbatim
+
+The remainder of the file should be quite familiar to you. Go ahead and
+run @code{tutorial-linear-dumbbell}. Now take a look at the trace
+(@code{tutorial.tr}) file. You will now see trace lines that begin with
+@code{d}. Alternatively you can search for the string ``queue-drop'' which
+is the expansion of the drop code ('d').
+
+Interpretation of a dropped packet is straightforward. We have expanded
+the first @code{queue-drop} trace for you below. See the section on ASCII
+tracing for details.
+
+@verbatim
+ 00 d
+ 01 2.40938
+ 02 nodeid=3
+ 03 device=1
+ 04 queue-drop
+ 05 pkt-uid=124
+ 06 LLCSNAP(type 0x800)
+ 07 IPV4(
+ 08 tos 0x0
+ 09 ttl 63
+ 10 id 20
+ 11 offset 0
+ 12 flags [none]
+ 13 length: 1052) 10.1.1.3 > 10.1.2.3
+ 14 UDP(length: 1032)
+ 15 49153 > 7
+ 16 DATA (length 1024)
+@end verbatim
+
+We leave it as an exercise to examine the trace files in more detail.
+
+@c ========================================================================
+@c Nonlinear Thinking
+@c ========================================================================
+
+@node Nonlinear-Thinking
+@chapter Nonlinear Thinking
+
+One thing that all of our examples so far have in common is that they are
+composed of a linear collection of calls into the @command{ns-3} system. The
+programmers among the readers may have wondered why there is not as much
+as a for-loop in all of the examples. The answer is that we wanted to
+introduce you to @command{ns-3} scripting with a minimum of conceptual
+overhead. We're going to remedy that situation shortly.
+
+We have written a number of @command{ns-3} scripts in C++. Although we have
+been perfectly linear in our script implementations, just like any other C++
+program, an @command{ns-3} script can use any features of the language you
+desire. If you will look back at the @code{tutorial-linear-dumbbell.cc}
+example, you may notice that the code to create the left and right sides of
+the dumbbell is operationally identical --- only the names change. An obvious
+improvement of this program would be to use subroutines to create the sides.
+Since we are working with C++, we should probably do this in an
+object-oriented way. Since object-oriented design is somewhat of a black art
+to some people, we'll take some time here and outline a simple methodology
+you can follow.
+
+@section Object Design 101 --- Class Ipv4BusNetwork
+If you are a master of object oriented design, feel free to skip or skim this
+section, in which we derive a simplistic but fully operational bus network
+class.
+
+So you want to create a BusNetwork class. Often the biggest hurdle in a
+design is figuring out how to get started. One of the simplest and most
+straightforward ways to do an object decomposition of a problem is to simply
+write down a description of the problem and take a look at the words
+you used. Let's take some time and do that, first at a very high level.
+
+@example
+A bus network is an implementation of a particular network topology that
+contains some number of nodes. Each of these nodes is attached to a single
+multi-drop channel. The network itself has some attributes independent of
+the topology such as a network mask, network number (prefix) and base IP
+address.
+@end example
+
+The first thing to do is to focus on the nouns and adjectives. These will
+give you a starting point for required classes and member variables.
+
+Immediately we can notice that at the highest level we are talking about the
+noun @emph{network}. This probably won't surprise you. We also have an
+adjective that modifies the noun --- @emph{bus}. This should lead us to our
+first class defintion. Usually class names are constructed in the same way
+as an English language sentence would be spoken. For example, one would speak
+of a @emph{bus network} in conversation, so we would normally create a
+@code{class BusNetwork} to represent it.
+
+One thing to note is that we have used two words in our description quite
+naturally: @emph{is} and @emph{has}. When you see these words should should
+immediately think of the object-oriented concepts of @emph{ISA} (inheritance)
+and @emph{HASA} (containment) respectively. We wrote that a bus network
+@emph{is} an implementation of a particular network topology. Perhaps you
+will agree that there is a natural base class called @code{Network} that
+@emph{has} the attributes discussed above. The fact that a @code{BusNetwork}
+@emph{ISA} kind of @code{Network} suggests inheritance. Let's capture that
+thought right away remembering that we're focused on IP version four here:
+
+@verbatim
+ class Ipv4Network
+ {
+ public:
+ Ipv4Address m_network;
+ Ipv4Mask m_mask;
+ Ipv4Address m_baseAddress;
+ };
+
+ class Ipv4BusNetwork : public Ipv4Network
+ {
+ };
+@end verbatim
+
+Let's take a look at the @emph{HASA} relationships of the bus network. Clearly
+it will @emph{have} a reference to the underlying channel that implements the
+actual communications medium. We use smart pointers for those references, so
+one member variable is obvious:
+
+@verbatim
+ Ptr<CsmaChannel> m_channel;
+@end verbatim
+
+A bus network will also need to contain references to all of the nodes we
+eventually want to create. If you are working in C++ and see the words contain
+or container, you should immediately think of the Standard Template Library
+or STL. A quick search of the available containers there will probably lead
+you to consider the vector class. A vector is a container that looks like an
+array. This is just what we need here. Again, we want to use smart pointers
+to reference our nodes, so the declaration of the vector would look like,
+
+@verbatim
+ std::vector<Ptr<Node> > m_nodes;
+@end verbatim
+
+It will save you headaches in the future if you notice that the space between
+the two right brackets is required to differentiate this situation from a
+right-shift operator. So we have a pretty good start already after just a
+little work. Now we need to turn our attention to actions. Let's write
+another little description of the things you consider doing to a Bus network.
+
+@example
+We need to be able to create a bus network. We need to be able to delete a
+bus network. We need to be able to get a handle to a node in order to add
+applications. We need to be able to set the network, mask and base address
+somehow, specify how many nodes to create and provide the underlying channel
+its required bandwidth and delay parameters.
+@end example
+
+We now look at the @emph{verbs} in that sentence. These will give a good
+starting point for the methods of the classes. For example, the verbs
+@emph{create} and @emph{delete} should suggest @emph{constructor} and
+@emph{destructor}. The verb @emph{get} leads us to providing a method called
+@code{GetNode}. We have to provide a number of parameters so we can either
+provide @emph{setters} or we can simply pass them in as parameters to our
+constructors. Since this is a simple example, we won't bother to implement
+getters and setters (methods to get and set member variables to enhance data
+hiding). Let's use this guidance to finish up our class declarations:
+
+@verbatim
+ class Ipv4Network
+ {
+ public:
+ Ipv4Network (Ipv4Address network, Ipv4Mask mask, Ipv4Address address);
+ virtual ~Ipv4Network ();
+
+ Ipv4Address m_network;
+ Ipv4Mask m_mask;
+ Ipv4Address m_baseAddress;
+ };
+
+ class Ipv4BusNetwork : public Ipv4Network
+ {
+ public:
+ Ipv4BusNetwork (
+ Ipv4Address network,
+ Ipv4Mask mask,
+ Ipv4Address startAddress,
+ DataRate bps,
+ Time delay,
+ uint32_t n);
+
+ virtual ~Ipv4BusNetwork ();
+
+ Ptr<Node> GetNode (uint32_t n);
+
+ private:
+ std::vector<Ptr<Node> > m_nodes;
+ Ptr<CsmaChannel> m_channel;
+ };
+@end verbatim
+
+That's it. We have actually already walked through almost all of the code
+required to construct a bus network in our @code{tutorial-csma-echo.cc}
+example, so let's just jump forward and take a look at an implementation
+of this thing. We provide an implementation for you in the files
+@code{ipv4-bus-network.h} and @code{ipv4-bus-network.cc} located in the
+@code{tutorial} directory. We also provide an example that uses the new
+class in the file @code{tutorial-bus-network.cc}.
+
+The interesting method from our current perspective is the Ipv4BusNetwork
+constructor, shown below:
+
+@verbatim
+ Ipv4BusNetwork::Ipv4BusNetwork (
+ Ipv4Address network,
+ Ipv4Mask mask,
+ Ipv4Address baseAddress,
+ DataRate bps,
+ Time delay,
+ uint32_t n)
+ :
+ Ipv4Network (network, mask, baseAddress)
+ {
+ Ipv4AddressGenerator::SeedNetwork (mask, network);
+ Ipv4AddressGenerator::SeedAddress (mask, baseAddress);
+
+ m_channel = CsmaTopology::CreateCsmaChannel (bps, delay);
+
+ for (uint32_t i = 0; i < n; ++i)
+ {
+ Ptr<Node> node = CreateObject<InternetNode> ();
+ uint32_t nd = CsmaIpv4Topology::AddIpv4CsmaNetDevice (node, m_channel,
+ Mac48Address::Allocate ());
+ Ipv4Address address = Ipv4AddressGenerator::AllocateAddress (mask,
+ network);
+ CsmaIpv4Topology::AddIpv4Address (node, nd, address, mask);
+ m_nodes.push_back (node);
+ }
+ }
+@end verbatim
+
+Notice that we do the simple and straightforward thing and pass all of our
+parameters to the constructor. For those unfamiliar with C++, the line after
+the colon and before the opening brace (shown below),
+
+@verbatim
+ :
+ Ipv4Network (network, mask, baseAddress)
+ {
+@end verbatim
+
+Passes the appropriate parameters to the constructor of the base class
+@code{Ipv4Network}. There are two new calls that we haven't seen immediately
+after this initialization. They are:
+
+@verbatim
+ Ipv4AddressGenerator::SeedNetwork (mask, network);
+ Ipv4AddressGenerator::SeedAddress (mask, baseAddress);
+@end verbatim
+
+We provide an IP address generator class to allow us to programatically
+allocate IP addresses. The first call to @code{SeedNetwork} gives the
+address generator a starting network number to use when generating addresses.
+The second call to @code{SeedAddress} gives the address generator a starting
+IP address to use. There is a starting network and starting address for each
+of the 32 possible network masks. Later in the for loop, you will see a
+call to @code{AllocateAddress} in which the IP address for each node created
+in the loop is actually generated.
+
+The only unfamiliar call in the reset of the constructor will be:
+
+@verbatim
+ m_nodes.push_back (node);
+@end verbatim
+
+This is the STL code to add the newly created node to the vector of nodes
+attached to the bus.
+
+For your convenience, we reproduce the entire bus network implementation below:
+
+@verbatim
+ /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+ /*
+ * Copyright (c) 2007 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+ #include "ns3/mac48-address.h"
+ #include "ns3/csma-net-device.h"
+ #include "ns3/csma-topology.h"
+ #include "ns3/csma-ipv4-topology.h"
+
+ #include "ipv4-bus-network.h"
+ #include "ipv4-address-generator.h"
+
+ namespace ns3 {
+
+ Ipv4Network::Ipv4Network (
+ Ipv4Address network,
+ Ipv4Mask mask,
+ Ipv4Address address)
+ :
+ m_network (network), m_mask (mask), m_baseAddress (address)
+ {
+ }
+
+ Ipv4Network::~Ipv4Network ()
+ {
+ }
+
+ Ipv4BusNetwork::Ipv4BusNetwork (
+ Ipv4Address network,
+ Ipv4Mask mask,
+ Ipv4Address baseAddress,
+ DataRate bps,
+ Time delay,
+ uint32_t n)
+ :
+ Ipv4Network (network, mask, baseAddress)
+ {
+ Ipv4AddressGenerator::SeedNetwork (mask, network);
+ Ipv4AddressGenerator::SeedAddress (mask, baseAddress);
+
+ m_channel = CsmaTopology::CreateCsmaChannel (bps, delay);
+
+ for (uint32_t i = 0; i < n; ++i)
+ {
+ Ptr<Node> node = CreateObject<InternetNode> ();
+ uint32_t nd = CsmaIpv4Topology::AddIpv4CsmaNetDevice (node, m_channel,
+ Mac48Address::Allocate ());
+ Ipv4Address address = Ipv4AddressGenerator::AllocateAddress (mask,
+ network);
+ CsmaIpv4Topology::AddIpv4Address (node, nd, address, mask);
+ m_nodes.push_back (node);
+ }
+ }
+
+ Ipv4BusNetwork::~Ipv4BusNetwork ()
+ {
+ }
+
+ Ptr<Node>
+ Ipv4BusNetwork::GetNode (uint32_t n)
+ {
+ return m_nodes[n];
+ }
+
+ }; // namespace ns3
+@end verbatim
+
+@section Using Ipv4BusNetwork
+If all you ever want to do with a bus network can be captured in a topology
+with four nodes on the bus, the preceeding section may seem like a colossal
+waste of time. This is probably not the case, though. Now that we have a
+relatively abstract bus class, we can create bus networks with 4, 40 or 4000
+nodes with no additional effort.
+
+A use of the bus network class is shown in the file
+@code{bus-netowrk.cc} located in the @code{tutorial} directory. The
+interesting code is,
+
+@verbatim
+ Ipv4BusNetwork bus ("10.1.0.0", "255.255.0.0", "0.0.0.3",
+ DataRate(10000000), MilliSeconds(20), 10);
+@end verbatim
+
+Here we create a bus network with the network number ``10.1.0.0'' and the
+network mask ``255.255.0.0'' that completes the IP network definition. You
+can consider these together as ``10.1.0.0/16'' if you prefer. The next
+parameter tells the bus to start numbering IP addresses of contained nodes at
+``10.1.0.3'' (remember the network number will be combined). We provided a
+data rate of 10 megabits per second and a latency of 20 milliseconds.
+Finally, we ask the @code{Ipv4BusNetwork} object to create ten nodes in the
+network.
+
+If you are feeling brave, go ahead and change the number of nodes to be 100,
+1000, 10,000 or more to generate larger and larger networks. Before you go
+too far, remember that a trace file will be generated when you run your
+resulting program and ee asked the trace facility to trace all net device
+receive events. This will include the reception of the broadcast ARP request
+by all of the nodes in the simulation, so this can add up quickly.
+
+@c ========================================================================
+@c Summary
+@c ========================================================================
+
+@node Summary
+@chapter Summary
+
+This concludes the first part of the tutorial. We have focused on
+using the @command{ns-3} system to construct various network topologies and to
+simulate sendng data across the networks; and we've shown you how to use the
+trace facility to get access to simulation results.
+
+We now encourage you to play with the system a little. Experiment with what
+we have provided. Build a hierarchical network simulation. Perhaps exercise
+your object design skills and create a new @code{Ipv4DumbbellNetwork} class
+to create dumbbell networks using the Ipv4BusNetwork class we just created.
+Hint: An Ipv4DumbbellNetwork @emph{has} two @code{Ipv4BusNetwork} objects;
+a left side and a right side.
+
+In the next part of the tutorial we are going to drop down a level and begin
+examining the lower levels of the system in more detail. We are going to
+explain how to change the behavior of the system and eventually how to write
+new models and applications. This is a good time to make sure that you
+thorougly understand what we've gone over so far.
+
+@c ========================================================================
+@c Object Model
+@c ========================================================================
+
+@node Object-Model
+@chapter Object Model
+
+@cindex Object Model
+There are two distinctly different meanings associated with the term Object
+Model. The first speaks to the implementation of an object system --- a system
+view; and the second speaks to the application programming interface (classes
+or objects) one uses to access some service or system --- an application view.
+
+As an example of the system view sense of the term, the C++ language has an
+associated object model that describes how objects are laid out in memory,
+how virtual functions work, how inheritance is implemented, constructor and
+destructor execution ordering, template instantiation, etc.
+
+@cindex API
+@cindex DOM
+@cindex Document Object Model
+In the case of the application view, the Document Object Model is a good
+example. In the words of W3C, the Document Object Model (DOM) is an
+application programming interface (API) for HTML and XML documents. It defines
+the logical structure of documents and the way a document is accessed and
+manipulated.
+
+@cindex API
+@cindex COM
+@cindex Component Object Model
+The Component Object Model (COM) from Microsoft actually spans both meanings
+of the term and extends further into policy statements. From a system
+perspective, COM specifies an interface definition language, the layout of
+objects virtual function tables, the formats of Globally Unique Identifiers
+and also specifies lifetime management mechanisms for objects via reference
+counting. From the point of view of the API, COM specifies a number of
+Interfaces as well as functions such as CoCreateInstance and various
+threading models. The COM specification extends to policy by disallowing
+implementation inheritance.
+
+@cindex Feynman
+The @command{ns-3} object model takes the C++ language (system level) object
+model as its basis, and extends that model by providing an API for software
+componentry. You may find terms like Component, Interface and QueryInterface
+in the following discussion, or used informally in other discussions about
+@command{ns-3}. It is important to understand from the outset that this is
+the @command{ns-3} object model, and not any other object model.
+Richard Feynman (an American physicist) once described the behavior of matter
+and light on a very small scale in the following way,
+
+@quotation
+``They do not behave like waves, they do not behave like particles, they do
+not behave like clouds, or billiard balls, or weights on springs, or like
+anything that you have ever seen.''
+@end quotation
+
+Just as students of quantum mechanics must rid themselves of preconceptions
+regarding the behavior of matter at small scales, you should rid yourself of
+any preconceptions you may have about components, interfaces and APIs for
+software componentry before continuing. To paraphrase Feynman, @command{ns-3}
+components do not behave like COM Components, or Java Beans, or CORBA
+objects, or clouds or weights on springs, or like anything that you have
+ever seen --- they are @command{ns-3} components.
+
+@section The C++ Object Model is the Root of all Things
+@command{Ns-3} is primarily a C++ system. The system is written in C++ and
+one can use standard C++ mechanisms for creating and using ns-3 objects. We
+do not change this at all, nor do we make any pronouncements about the
+superiority of one mechanism or another. What we will do is provide
+convenience functions that we think will make creating and managing simulation
+objects easier.
+
+@cindex CreateObject
+Previously, you have seen objects created using the template function
+@code{CreateObject} as in the following example:
+
+@verbatim
+ Ptr<Node> n0 = CreateObject<InternetNode> ();
+@end verbatim
+
+This line of code, while it may be unfamiliar to some, is pure C++. If you
+were to look in the header file ptr.h, you would find the following definition
+of the @code{CreateObject} template.
+
+@verbatim
+ template <typename T>
+ Ptr<T> CreateObject (void)
+ {
+ Ptr<T> p = Ptr<T> (new T (), false);
+ p->SetTypeId (T::GetTypeId ());
+ return p;
+ }
+@end verbatim
+
+@cindex template
+As you can see, this template creates objects of type @code{T} using the
+operator @code{new}. Its a little harder to find the corresponding delete ---
+it's in the file @code{object.cc} inside the method @code{Object::MaybeDelete},
+but when that @code{Ptr} which you see above goes out of scope it will call
+@code{Unref} and ultimately the C++ @code{delete} operator will be called.
+
+@cindex new
+@cindex delete
+The ns-3 system uses the C++ @code{new} and @code{delete} operators, so there
+is really no reason that you as a user of the ns-3 system are forbidden from
+using these or any other C++ mechanism. If you so desire, you can take on
+the responsibility for managing object lifetime (i.e., do not use the
+@code{Ptr} smart pointer), work directly with the @code{new} and @code{delete}
+operators and call methods like any C++ object as in the following example:
+
+@verbatim
+ MyClass *obj = new MyClass ();
+ obj->Method();
+ delete obj;
+@end verbatim
+
+@cindex model
+You, as a competent model author, are encouraged to use whatever methods you
+think are appropriate in your private code. Remember, however, that the
+public ns-3 APIs do use smart pointers to pass objects around in an effort to
+reduce the burden of object lifetime management. If you do intend to export
+an API publicly, you should use the same object lifetime management approaches
+as those found in the ns-3 public API if only for consistency.
+
+These APIs are there for convenience and consistency, but do not change the
+fact that in ns-3 all of the objects are really just C++ objects, ultimately
+created using the C++ new operator with C++ constructor semantics and are
+ultimately deleted using the C++ delete operator, following C++ destructor
+semantics. Although it may sometimes appear so, there is really no system-
+level magic going on in ns-3. Ns-3 components and interfaces are C++ objects
+just like any other object and our object model is simply a collection of APIs
+built on the normal C++ object model.
+
+@cindex Interface
+@cindex Abstract Data Type
+@cindex ADT
+@cindex Abstract Base Class
+@cindex ABC
+@section Interface
+There are many different ideas floating around of what exactly the term
+@emph{interface} means. Originally an interface just meant a communication
+boundary between two entities. As the concepts of object oriented programming
+(OOP) were surfacing in the 1980s, the term interface was applied to the
+collection of access methods for the modular entities that were being defined.
+
+@cindex OOP
+@cindex Object Oriented Programming
+Two distinct approaches developed regarding specifying access mechanisms for
+objects. The OOP purists were very concerned about object reuse and were led
+to Abstract Data Types (ADT). These were eventually implemented in the case
+of C++, as pure virtual methods in Abstract Base Classes (ABC). Another group
+of folks was more interested in simply specifying object access methods in one
+place and using inheritance as the primary reuse mechanism.
+
+Bjarne Stroustroup, the creator of C++, embraced both approaches. He makes
+the following interesting observation:
+
+@quotation
+``Many classes [@dots{}] are useful both as themselves and also as bases for
+derived classes. [@dots{}] Some classes, such as class @strong{Shape},
+represent abstract concepts for which objects cannot exist.''
+@end quotation
+
+@cindex PIMPL
+@command{Ns-3} does not pick and enforce a particular approach. In
+@command{ns-3} an interface is determined completely by a class declaration
+just as any C++ object interface is declared. If you think of an object as
+an abstract concept that should be implemented by derived classes, by all
+means, use the Abstract Base Class approach to interface declaration. If you
+think that an object should be completely concrete and you foresee no need
+to ever modify its behavior, feel free to avoid declaring any methods virtual.
+If you think that an object could be useful as a base class, feel free to
+declare its methods virtual. If you like to use the PIMPL idiom, again, feel
+free. If you want to use any combination of these techniques, feel free.
+We make no restrictions.
+
+@cindex API
+When we speak of an ns-3 interface, we do not worry about interface definition
+languages, or pure virtual classes, or registries we just think about C++
+object declarations and their associated methods. We tend to think of
+interfaces to objects as simply a private or public API. When we instantiate
+an @command{ns-3} interface, it is the C++ object model that dictates how that
+object is brought into existence. When a method is called on an @command{ns-3}
+Interface, it is the C++ object model that dictates how that method is
+dispatched.
+
+We do, however, provide a base class that endows vanilla C++ objects with
+capabilities that can be seen as conceptually similar to those provided by
+Microsoft Component Model @emph{Interfaces}.
+
+@section The Ns-3 Object and GetObject
+@cindex Component Object Model
+One thing that Microsoft arguably got right in the Component Object Model was
+the idea of Interface aggregation and discovery via QueryInterface. We have
+embraced these ideas in @command{ns-3}. This was done primarily to address a
+common problem in large software systems. A good example of this problem
+happens in the @command{ns-3} Node class.
+
+@cindex OOP
+@cindex weak base class
+@cindex base class bloat
+@cindex Swiss Army Knife class
+@cindex Node
+If one were to take the standard OOP view of specializing a @code{Node} into
+an internet host, for example, one would typically inherit from the @code{Node}
+base class and include functionality to implement such things as internet
+routing and a TCP/IP protocol stack. Other types of @code{Node}s might
+inherit from the node class and specialize in different ways, or further
+specialize the internet host class, treating it as a base class. This can
+result in a complicated inheritance tree in which some specializations are
+simply not available to other branches of the tree which can make reuse
+difficult or impossible. This is known as the @emph{weak base class} problem
+and creates pressure to drive functionality up the inheritance tree into the
+base classes. This, in turn, results in @emph{base class bloat} and the
+resulting @emph{swiss army knife} base classes which end up trying to do
+everything in one place.
+
+Even if one successfully avoided these swiss army knife base classes, one
+would also want to be able to treat new specializations of @code{Node}
+generically in the system. This means one would pass references to the base
+class (@code{Node}) across public APIs. This introduces @emph{upcasts} prior
+to passing across public APIs and corresponding @emph{downcasts} on the other
+side in order to gain access to required specialized functions. As the
+inheritance tree becomes more complicated, this approach can cause another
+related problem known as the @emph{fragile base class} problem. This happens
+when changes to the base class cause unexpected problems in the various and
+sundry subclasses.
+
+These effects seem always to result in a positive feedback loop driving
+everything into the base class and destroying much of the encapsulation which
+is a hallmark of the object oriented approach.
+
+@subsection Interface Composition
+@cindex Node
+There is a completely different way to address the Node specialization
+problem. Instead of approaching the situation using inheritance, one can
+look at the problem as one of composition. We can look at the @code{Node}
+class as a container of sorts that holds other objects. In this case, the
+objects would be instances of the classes implementing the internetwork
+routing code, or the TCP/IP protocol stack described above. This approach
+preserves the encapsulation and solves the weak base class, base class bloat
+and fragile base class problems; but the question of method dispatch
+immediately comes to mind.
+
+@cindex delegation
+In many systems, @emph{delegation} is used. The base class, @code{Node},
+in this approach would provide methods that simply forward to the objects
+implementing the desired functionality. This situation clearly does not
+address the base class bloat problem since dispatch methods must be added
+to the base class. The situation is mitigated somewhat by pushing the
+implementation of the dispatch methods to contained objects, but the
+fundamental problems are still present. What is really needed is a way
+to compose objects but at the same time keep the interfaces to those
+objects separated.
+
+@cindex aggregation
+Composition, usually called @emph{aggregation}, along with runtime Interface
+discovery is the solution that Microsoft originally championed and that
+@command{ns-3} has adopted --- albeit with many simplifications and a few name
+changes.
+
+@subsection Objects and Interfaces
+@cindex COM
+@cindex QueryInterface
+Now that we have mentioned Microsoft COM and are almost obligated to mention
+the terms Interface and QueryInterface. For those familiar with COM, loosely
+speaking, QueryInterface is to COM as GetObject is to @command{ns-3}.
+The analogy, while good conceptually, is superficial from an implementation
+point of view.
+
+@cindex Node
+Addressing our current example of a @code{Node}, generically speaking, each
+node needs to aggregate an object that will implement internetwork routing
+and TCP/IP. The system will need to provide a mechanism for locating the
+aggregated objects and allow a client to discover them.
+
+@cindex aggregation
+@cindex Object
+These aggregated objects have interfaces in the C++ sense of collections of
+method signatures. In @command{ns-3}, when objects are capable of
+participating in this aggregation process, they are called @command{ns-3}
+@code{Objects}. @code{Objects} receive the functionality required for this
+ participation by inheriting from the @command{ns-3} base class @code{Object}.
+
+Note well that when we write the word @code{Object} (note the uppercase 'O' in
+the spelling and the change of font) we are referring to a kind of C++ object
+that has inherited the capability of participating in an aggregation. The
+@command{ns-3}-specific word @code{Object} can have a significantly different
+meaning than that of a vanilla C++ object outside the aforementioned
+inheritance tree, and the difference is only readily apparent via context.
+In this tutorial we will always write the @command{ns-3}-specific kind of
+@code{Object} in a fixed font; and will write the vanilla C++ term object in
+normal font. In conversation, you will need to be careful to understand which
+term is meant: object or @code{Object}.
+
+Once an object has inherited from class @code{Object} it has the ability to
+@emph{host} an aggregation. This means that it has the ability to add other
+@code{Objects} to its aggregation via the method @code{AggregateObject}. It
+also means that it can provide a service to @emph{discover} other objects in
+its aggregation via the method @code{GetObject}.
+
+@cindex base class
+Technically, the class named @code{Object} is simply a base class that you
+will inherit from if you want your @code{Objects} to support aggregation and
+discovery. Many systems have a base class that implements common
+functionality and these base classes are typically called somthing like
+Object. The @command{ns-3} version of this base class relates primarily to
+@code{Object} aggregation and discovery, although it does also provide methods
+to help with intrusive reference counting and tracing as well.
+
+When a C++ object inherits from the ns-3 Object base class, it is conceptually
+promoted to an ns-3 @code{Object} irrespective of how the object was declared
+(e.g., as an abstract base class, concrete class, with virtual methods, etc.).
+In ns-3, you should associate inheritance from the class named @code{Object}
+with promotion of an object to the status of some locatable @code{Object}
+rather than with the form of the class declaration.
+
+@cindex COM
+@cindex CORBA
+@cindex ORBit
+For those of you unfamiliar with Microsoft COM, CORBA or ORBit, this might
+sound obvious. For those of with such a background, the point we are making
+is that there is no such thing in @command{ns-3} as a separate Interface
+declaration, no such thing as an Interface Definiition Language, no such thing
+as a UUID or GUID, etc. In @command{ns-3} we just work with C++ objects that
+may be given some very useful abilities by inheriting from the @command{ns-3}
+base class @code{Object}. @command{Ns-3} @code{Objects} are not required to
+inherit from classes composed of pure virtual methods in order to define an
+Interface. It's all really just ``plain old C++.''
+
+To summarize, when you instantiate an object that inherits from the
+@code{Object} class, you will have a C++ object that has four important
+properties:
+
+@cindex AggregateObject
+@cindex GetObject
+@itemize @bullet
+@item The @code{Object} has a C++ interface defined by the collection of method signatures in its inheritance tree;
+@item The @code{Object} has some way to identify its underlying class uniquely;
+@item The @code{Object} is a kind of container that has the ability to aggregate other @code{Objects} using the method @code{AggregateObject};
+@item The @code{Object} exports a method called @code{GetObject} that allows for discovery of other aggregated @code{Objects}.
+@end itemize
+
+@cindex base class
+@cindex Object
+It is crucially important to understand what we have described here
+(especially for those coming from other systems that provide similar
+functionality). A given C++ class has an object access interface that is
+essentially the collection of method signatures specified in its inheritance
+tree. This is a C++ object model thing. Ns-3 provides a base class from
+which the class in question can inherit and be promoted to the status of
+@code{Object}. Once a class becomes an @code{Object} it has inherited the
+ability to aggregate and search for other @code{Objects} that are added to
+its aggregation.
+
+That last detail is important. In @command{ns-3} @code{Objects} are both
+containers and specifications for a object method access. We have previously
+mentioned that the @code{Node} class acts as a container. In fact, the
+@code{Node} class inherits from @code{Object} and is itself an @command{ns-3}
+@code{Object}. So, when the @code{Node} object is created it is really an
+aggregation of one @code{Object} and you can call @code{AggregateObject} or
+@code{GetObject} on the resulting @code{Node} object. Along with being an
+aggregation, the @code{Node} class also describes a public interface. THis
+public interface (API) is declared just as any C++ object is declared, via its
+class methods as specified in the inheritance tree. For those steeped in
+COM or CORBA, this is where the concept of Interface works in @command{ns-3}.
+Remember that it is generally true that @code{Objects} are both aggregations
+and APIs.
+
+@subsection Aggregations
+@cindex aggregate
+The figure below shows how an @code{Object} could be illustrated in detail.
+The line with the circle at the top of the diagram represents the appearance
+of the @code{Object} API to the external world. This circle and line are
+together called a lollipop because of its superficial similarity to a kind of
+childs candy.
+
+@sp 1
+@center @image{oneobj,,,,png}
+
+@cindex API
+You could declare this API and associated @code{Object} quite simply using a
+non-virtual class as follows,
+
+@verbatim
+ class A : public Object {
+ public:
+ static ns3::TypeId GetTypeId (void)
+ {
+ static ns3::TypeId tid = ns3::TypeId ("A")
+ .SetParent (Object::GetTypeId ())
+ .AddConstructor<A> ();
+ return tid;
+ }
+
+ A ()
+ {
+ }
+
+ void MethodA (void);
+ };
+@end verbatim
+
+The methods that are then available via the API labeled @code{A} in the
+figure above are the methods inherited from the @code{Object} base class
+(@code{GetObject}, @code{Ref}, and @code{Unref}) and those from class
+@code{A} (@code{MethodA}).
+
+Note that you must declare a @code{TypeId} in your @code{Object} class, and
+it must be declared static to make it class-wide in scope. This @code{TypeId}
+is a unifying element in the @command{ns-3} object model and uniquely
+identifies @code{Objects} at run-time as being instantiated from a particular
+class. We'll have much more to say about @code{TypiId} shortly.
+
+You can think of the arc and arrow device coming off each side of the
+illustrated @code{Objects} as part of a connector. These connectors allow
+@code{GetObject} to search aggregations for an instance of a class type.
+The figure below shows an aggregation of three @code{Objects}: A, B and C.
+The class declarations for classes @code{B} and @code{C} are substantially
+similar to that of class @code{A}.
+
+@sp 1
+@center @image{threeobj,,,,png}
+
+You can visualize these @code{Objects} as being snapped together like Lego
+building blocks if you like. When @code{Objects} are aggregated, a
+@code{GetObject} search path is formed through the connectors. In order
+to create this aggregation you will first need to create the @code{Objects}.
+These are just normal, everyday C++ objects that we can create using the
+@code{CreateObject} template function and manage using smart pointers. The
+following code should be obvious to you by now:
+
+@verbatim
+ Ptr<A> a = CreateObject<A> ();
+ Ptr<B> b = CreateObject<B> ();
+ Ptr<C> c = CreateObject<C> ();
+@end verbatim
+
+@cindex aggregation
+When you create an aggregation, you pick one of the @code{Objects} of the
+aggregation to think of as the container. In this case well pick @code{Object}
+A. In order to aggregate an @code{Object}, you simply call the method
+@code{AggregateObject} that your class has inherited from class @code{Object}.
+The following code will aggregate @code{Object B} and @code{Object C} onto
+the @code{Object} (and container/aggregation) @code{A}.
+
+@cindex AggregateObject
+@cindex GetObject
+@cindex Object
+@verbatim
+ a->AggregateObject (b);
+ a->AggregateObject (c);
+@end verbatim
+
+Thats all there is to it. Now that you have those connectors snapped
+together, you can ask each of the @code{Objects} in the aggregation for any of
+the other @code{Objects} in the aggregation. Lets look at a simple example:
+
+@verbatim
+ Ptr<B> newB = a->GetObject<B> ();
+@end verbatim
+
+Now, the explanation of what this snippet does is not as simple as writing it.
+The left hand side of this assignment declares a smart pointer to the class
+@code{B} to help with memory management of the returned @code{Object} pointer.
+You should be very familiar with smart pointers at this stage of the tutorial.
+
+The right hand side illustrates how @code{GetObject} is acutally used.
+The method @code{GetObject} is templated. The assocated template parameter
+(between the brackets) specifies the @emph{class} that is being requested.
+This is important. Since it is the class type that specifies the search
+criteron, there can be only one instance of a particular class present in an
+aggregation. Looking back a little, although the parameter to
+@code{AggregateObject} appears to be a vanilla C++ object (@code{b} or @code{c}
+above), it actually represents (is an instance of) a class that has an
+associated @code{TypeId} and inherits from @code{Object}. When you call
+@code{GetObject} you specify the search criterion (using the template
+parameter) as a class name. This referenced class must also have an
+associated @code{TypeId} and must also have inherited from @code{Object}.
+
+This may be summarized by saying that @code{AggregateObject} takes an
+@emph{instance} of an object of a particular class that inherits from
+@code{Object}. GetObject looks for a @emph{class} of a particular type
+(that again inherits from @code{Object}) and possibly returns an aggregated
+object instance of that type.
+
+Now that you have those conceptual connectors snapped together, you can ask
+each of the @code{Objects} in the aggregation for any of the @code{Objects}
+in the aggregation. For example we could walk the @code{Objects} asking each
+for the next in the aggregation. First we would ask the @code{Object} pointed
+to by the smart pointer @code{a} to look for the @code{Object} @code{class B}:
+
+@verbatim
+ Ptr<B> newB = a->GetObject<B> ();
+@end verbatim
+
+Next, we can ask the @code{Object} pointed to by the smart pointer @code{newB}
+to look for the @code{Object} representing @code{class C}:
+
+@verbatim
+ Ptr<C> newC = newB->GetObject<C> ();
+@end verbatim
+
+@cindex Object
+Then, we can ask the @code{Object} pointed to by the smart pointer @code{newC}
+to look for the @code{Object} representing @code{class A} and complete our
+circuit of the aggregation:
+
+@verbatim
+ Ptr<A> newA = newC->GetObject<A> ();
+@end verbatim
+
+@cindex GetObject
+@code{GetObject} has some important properties that we need to go over.
+Technically, @code{GetObject} is a @emph{symmetric}, @emph{reflexive} and
+@emph{transitive} operation with respect to the set of aggregated
+@code{Objects}.
+
+@subsubsection Symmetry
+@cindex symmetry
+The symmetric nature of @code{GetObject} guarantees that if one performs a
+@code{GetObject} on a given @code{Object} for the class of that same
+@code{Object}, that @code{GetObject} must succeed. In other words, the
+fact that you accessed the aggregation via an instance of an @code{Object A}
+in the aggregation implies the reachability of that @code{Object} in the
+aggregation. This is usually written (by Microsoft) as,
+
+@center must succeed (A >> A)
+
+We can illustrate this property with the code snippet,
+
+@verbatim
+ Ptr<A> symmetricA = a->GetObject<A> ();
+ NS_ASSERT (symmetricA);
+@end verbatim
+
+Here we take as given an interface (smart) pointer --- named @code{a} --- on
+which we perform a @code{GetObject} looking for the class that represents that
+same @code{Object}. This call must always succeed and a smart pointer to the
+aggregated instance of that class is returned.
+
+@subsubsection Reflexivity
+@cindex reflexivity
+Calls to @code{GetObject} must also be reflexive. This means that if you
+successfully @code{GetObject} for @code{Object B} from @code{Object A}, then
+you must always be able to @code{GetObject} for @code{A} from @code{B}. This
+is usually written as,
+
+@center must succeed (A >> B, then B >> A)
+
+This property can be illustrated with the code snippet,
+
+@verbatim
+ Ptr<B> b = a->GetObject<B> ();
+ Ptr<A> reflexiveA = b->GetObject<A> ();
+ NS_ASSERT (reflexiveA);
+@end verbatim
+
+If the first @code{GetObject} on @code{Object A} looking for @code{Object B}
+succeeds, then a @code{GetObject} on @code{Object B} looking @code{Object A}
+must succeed.
+
+@subsubsection Transitivity
+@cindex transitivity
+@code{GetObject} must also be transitive. This means that if one can
+find @code{Object B} from @code{Object A}, and @code{Object C} from
+@code{Object B}, then one must also be able to find @code{Object C} from
+@code{Object A}. This is usually written as,
+
+@center must succeed (A >> B, and B >> C, then A >> C)
+
+This property can be illustrated with the code snippet,
+
+@verbatim
+ Ptr<B> b = a->GetObject<B> ();
+ Ptr<C> c = b->GetObject<C> ();
+ Ptr<C> transitiveC = a->GetObject<C> ();
+ NS_ASSERT (transitiveC);
+@end verbatim
+
+If you can get to @code{Object B} from @code{Object A}, and you can get to
+@code{Object C} from @code{Object B}, then a @code{GetObject} on
+@code{Object A} looking for @code{Object C} must also succeed.
+
+@subsection Creating the TypeId
+@cindex TypeId
+@cindex GetTypeId
+The final piece of this puzzle is the @code{TypeId}. Recall that the
+declaration our eample object above included the following code
+
+@verbatim
+ static ns3::TypeId GetTypeId (void)
+ {
+ static ns3::TypeId tid = ns3::TypeId ("A")
+ .SetParent (Object::GetTypeId ())
+ .AddConstructor<A> ();
+ return tid;
+ }
+@end verbatim
+
+This is the bit of code that ties this all together. For those unfamiliar
+with the idioms involved, this declaration can be rather dense. First, let's
+examine the function declaration itself. The following code,
+
+@verbatim
+ static ns3::TypeId GetTypeId (void) ...
+@end verbatim
+
+declares a function that will be associated with all of the instances of the
+given class. This is a function, not a method, in that it can be accessed
+without a @emph{this} pointer; but it is associated with the class in a
+namespace sense. The use of this kind of declaration allows one to write,
+
+@verbatim
+ return A::GetTypeId (void);
+@end verbatim
+
+if the @code{TypeId} is needed for our @code{class A}. More generically the
+class name can be substituted in a template, as is done deep in the
+@command{ns-3} object system.
+
+From this perspective, if you leave out the middle of the function definition,
+the boundaries should make sense to you.
+
+@verbatim
+ static ns3::TypeId GetTypeId (void)
+ {
+ return tid;
+ }
+@end verbatim
+
+@cindex function-local variable
+You are obviously looking at a global function associated with your class
+that simply returns a @code{TypeId}. Now, what about the rest. The code
+
+@verbatim
+ static ns3::TypeId tid = ns3::TypeId ("A")
+ .SetParent (Object::GetTypeId ())
+ .AddConstructor<A> ();
+@end verbatim
+
+when found inside the function declaration is called a function-local variable
+with associated initialization. It'll be easier to pick this statement apart
+piece by piece as well. The first line,
+
+@verbatim
+ static ns3::TypeId tid = ...
+@end verbatim
+
+is the declaration of the function-local variable tid. This is essentially
+an initialized global variable, the scope of which has been reduced to within
+the enclosing method. You can think of this as a kind of global variable
+that can only be accessed right there where it is created. If the variable
+is initialized, this amounts to the same behavior as if a global static
+initializer was declared in a namespace of the same name as your class.
+Global static initializers are guaranteed by the C++ language definition to
+be executed before your main procedure is entered. So are function-local
+variables.
+
+The variable that is being initialized is of type @code{ns3::TypeId}, is
+named @code{A::tid} since it is inside the class declaration for
+@code{class A}, and is initialized by a call to the constructor for the class
+@code{TypeId}. The constructor for @code{TypeId} takes a @code{std::string}
+that can be used to locate the type information for your class. We usually
+privide the class name as the string.
+
+Hopefully, this much of the declaration is now clear:
+
+@verbatim
+ static ns3::TypeId GetTypeId (void)
+ {
+ static ns3::TypeId tid = ns3::TypeId ("A")
+ ...
+ return tid;
+ }
+@end verbatim
+
+All that is left now are the lines including @code{SetParent} and
+@code{AddConstructor}.
+
+@verbatim
+ static ns3::TypeId tid = ns3::TypeId ("A")
+ .SetParent (Object::GetTypeId ())
+ .AddConstructor<A> ();
+@end verbatim
+
+The last bit may seem quite odd at first glance, but don't let the way the
+code is broken up over several lines throw you. If you saw something like,
+
+@verbatim
+ pointer->TypeId()->SetParent()->AddConstructor();
+@end verbatim
+
+you probably wouldn't hesitate at all. Clearly, you would think, a method
+called @code{TypeId} is called using the pointer called @code{pointer} as
+shown below.
+
+@verbatim
+ pointer->TypeId()
+@end verbatim
+
+The method @code{TypeId} must further return a pointer to an object that has
+a method called @code{SetParent}. Just as clearly, @code{SetParent} must
+return a pointer to an object that has a method called @code{AddConstructor}.
+The same sort of thing is happening in our code snipped, except we are using
+references instead of pointers. Perhaps if we rearrange this code to live on
+one line it will be clearer.
+
+@verbatim
+ ns3::TypeId ("A").SetParent (Object::GetTypeId ()).AddConstructor<A> ();
+@end verbatim
+
+It's just a string of method calls. The remaining question is then, what do
+those three methods do.
+
+The first, @code{ns3::TypeId ("A")}, simply allocates a new type in the system
+and allows you to refer to it in the future by a string. We have mentioned
+inheritance trees often in the previous discussion. The second method,
+@code{SetParent} associates the class being defined with its parents in the
+tree. Finally, the @code{AddConstructor} method allows you to specify a
+constructor to be used when an instance of your class is created using
+@code{CreateObject}.
+
+@verbatim
+ AddConstructor<A> ();
+@end verbatim
+
+You can interpret this as explaining to the @command{ns-3} object ssytem that
+you have a constructor named @code{A::A} which takes no parameters. You are
+saying that this constructor should be used when @code{CreateObject} is called
+with no parameters.
+
+By including the structure of the inheritance tree, in @command{ns-3} we can
+use implementation inheritance to easily create new @code{Objects}. You are
+prevented from doing so in Microsoft COM, but this was almost universally
+identified as a problem.
+
+So, looking at the entire @code{GetTypeId} declaration again,
+
+@verbatim
+ static ns3::TypeId GetTypeId (void)
+ {
+ static ns3::TypeId tid = ns3::TypeId ("A")
+ .SetParent (Object::GetTypeId ())
+ .AddConstructor<A> ();
+ return tid;
+ }
+@end verbatim
+
+it should be clear what is happening.
+
+@subsection A Very Real Example
+@cindex Node
+@cindex AggregateObject
+@cindex GetObject
+@cindex Object
+At this point you may be asking yourself what the point of all of this is,
+since you already had those pointers laying around when you created the
+objects. The typical case is that one will create and aggregate some number
+of @code{Objects} in a constructor and return only a pointer to a single
+@code{Object} as in our canonical example with @code{class Node}. In this
+case, the @code{Node} would be created and the @code{Node} constructor might
+create and call @code{AggregateObject} to aggregate the @code{Objects} for
+internetwork routing and TCP/IP. From an external point of view, these
+aggregated objects may be discovered at run-time using @code{GetObject}.
+
+Generally one tends to think of one of the @code{Objects} in the aggregation
+as being the container and other @code{Objects} being aggregated to that
+container. In the case of a Node, for example, it is quite natural to think
+of the Node as being the container which contains protocol stacks, internet
+routing, etc. So, lets start thinking about a real example by calling the
+container @code{Object Node} instead of @code{A} as we have been. The
+creation of this @code{Object} is found all over our example programs. For
+example, you will find code like the following in
+@code{samples/simple-point-to-point.cc}:
+
+@verbatim
+ Ptr<Node> n = CreateObject<InternetNode> ();
+@end verbatim
+
+It may appear obvious to you now that the @code{InternetNode} class name
+provided to the template function @code{CreateObject} means that
+@code{InternetNode} is an @command{ns-3} @code{Object} and you will be able to
+call @code{GetObject} on the resulting smart pointer. Well, I'm afraid that's
+not entirely true. It's slightly more complicated.
+
+Take a look at @code{src/internet-stack/internet-stack.h} and find the class
+declaration for @code{InternetNode}.
+
+@verbatim
+ class InternetNode : public Node
+ {
+ public:
+ InternetNode();
+ ...
+ };
+@end verbatim
+
+@cindex GetTypeId
+@cindex TypeId
+@cindex Object
+There is no declaration of a @code{static TypeId GetTypeId (void)} in this
+class. This means that the @code{InternetNode} is really not an @code{Object}
+for which you can @code{GetObject}. It turns out that the @code{InternetNode}
+is an @emph{implementation class} of the @code{Node Object}.
+
+You may recall that there can be an implicit cast in a smart pointer
+assignment if the cast is to a visible, unambiguous base class. That is, in
+fact, what is happening here. Now, take a look at @code{src/node/node.h} and
+find the class declaration for @code{class Node}. There you will find,
+
+@verbatim
+ class Node : public Object
+ {
+ public:
+ static TypeId GetTypeId (void);
+ ...
+ };
+@end verbatim
+
+Class @code{InternetNode} inherits from class @code{Node} that, in turn,
+inherits from class @code{Object}. It is @code{Node} that provides a
+@code{GetTypeId} method. Therefore it is @code{Node} that is an
+@command{ns-3} @code{Object}. Note well that @code{InternetNode} is not an
+@code{Object} in the sense that one should call @code{GetObject} on an
+aggregation looking for an @code{InternetNode} class. That is, you should not
+do,
+
+@verbatim
+ Ptr<InternetNode> i = node->GetObject<InternetNode> ();
+@end verbatim
+
+since there really is not InternetNode::GetTypeId. It is @code{Node} that is
+the @emph{proper} @code{Object} in this case and you should view
+@code{InternetNode} as an implementation of the @code{Node Object}. This may
+become clearer as we look a little deeper.
+
+We spoke of a protocol stack that is aggregated to a @code{Node} in our
+discussions above, what we see in the real @command{ns-3} code is that this
+is represented by the @code{Ipv4 Object}. If you look in
+@code{src/node/ipv4.h} you will find,
+
+@verbatim
+ class Ipv4 : public Object
+ {
+ public:
+ static TypeId GetTypeId (void);
+ ...
+ };
+@end verbatim
+
+Since class @code{Ipv4} inherits from class @code{Object} and has a
+@code{GetTypeId}, it is an @command{ns-3} @code{Object}. If you look in
+@code{src/node/ipv4.cc} you will find,
+
+@verbatim
+TypeId
+Ipv4::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("Ipv4")
+ .SetParent<Object> ();
+ return tid;
+}
+@end verbatim
+
+After all of this reading you know that this code snippet is asking the
+system to create a unique @code{TypeId} for the @code{Ipv4} class and
+declares that @code{Ipv4} inherits from class @code{Object}. This is what
+makes an @code{Ipv4} an @code{Object}.
+
+@cindex Ipv4
+It turns out that the Ipv4 class is an abstract base class (ABC). There are
+a number of pure virtual methods declared in that class. This means that
+an @code{Ipv4} object may not be instantiated. This is reflected by the fact
+that there are no constructors registered in the @code{GetTypeId} method above.
+What is instantiated in the real system is an implementation class, called
+@code{Ipv4Impl}. This class inherits from @code{Ipv4} and provides the
+required virtual methods. This is where understanding what is an
+@code{Object} and what is not can get tricky. The @code{Object} is the
+@code{Ipv4} class since that is where the @code{GetTypeId} is found. The fact
+that you see @code{GetTypeId} there tells you that the @code{Ipv4} class is
+the class for which you can @code{GetObject}.
+
+@cindex implementation class
+The class @code{Ipv4Impl} provides an implementation for the pure virtual
+methods in @code{Ipv4}. Since class @code{Ipv4} cannot be instantiated, one
+instantiates the @code{Ipv4Impl} class to create an @code{Ipv4} @code{Object}.
+You will use the @code{CreateObject} template function to create an object that
+implements the methods of an @code{Object}. You can probably see how this
+gets even more tricky in conversation.
+
+Once the @code{Ipv4Impl} object is instantiated, the resulting pointer is
+immediately cast to an @code{Ipv4} pointer. Clients will then use the
+methods specified in the @code{Ipv4} class to access the @code{Ipv4 Object}
+methods which are, in turn, implemented in the @code{Ipv4Impl} object.
+
+If you now look in the file, @code{src/internet-stack/internet-stack.cc} you
+will see the following code in @code{InternetNode::Construct} that creates the
+@code{Ipv4} Interface and aggregates it.
+
+@verbatim
+ Ptr<Ipv4Impl> ipv4Impl = CreateObject<Ipv4Impl> (ipv4);
+ ...
+ Object::AggregateObject (ipv4Impl);
+@end verbatim
+
+Note that the parameter @code{ipv4} passed to the @code{CreateObject} template
+function is actually a pointer to an @code{Ipv4L3Protocol} which you can
+ignore at this point --- it doesn't really have anything to do with the
+@code{Ipv4} Interface.
+
+This is exactly the same thing that is happening in the case of the
+@code{InternetNode}.
+
+@verbatim
+ Ptr<Node> n = CreateObject<InternetNode> ();
+@end verbatim
+
+@cindex implementation object
+@code{CreateObject} is being called to create an implementation object,
+in this case @code{InternetNode}, which implements the methods of the
+@code{Node Object}. It is the resulting @code{Node Object} which you would
+use as the container and it is the @code{Node} class that you would use as
+the template parameter when calling @code{GetObject}. In the same way, you
+would @emph{not} want to do,
+
+@verbatim
+ Ptr<Ipv4> ipv4 = node->GetObject<Ipv4Impl> ();
+@end verbatim
+
+Rather you should understand that the @emph{proper} @code{Object} is the
+@code{Ipv4} not the @code{Ipv4Impl} and do the following,
+
+@verbatim
+ Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
+@end verbatim
+
+@cindex CreateObject
+This does illustrate that the fact that whether an object created by
+@code{CreateObject} is or is not an @code{Object} in the usual sense can be
+quite well hidden if you are casually looking at the object creation code.
+The designers of the system had long and involved discussions on this issue
+and in the end decided that mnemonic aids such as Hungarian notation were a
+stylistic thing and you should just refer to the system documentation to
+determine what objects are @command{ns-3} @code{Objects} and what the APIs
+of those @code{Objects} actually are (RTFM --- as in Read the Fine Manual,
+of course).
+
+@cindex AggregateObject
+@cindex Object
+In the case of @code{Ipv4Impl}, you know that the class inherits somehow
+from @code{Object} since there is a call to @code{AggregateObject} that
+refers to an instance of an @code{Ipv4Impl}. You will have to go to
+the header file @code{src/internet-stack/ipv4-impl.h} and find that
+@code{Ipv4Impl} inherits from class @code{Ipv4}. You will then have go to
+the file @code{src/node/ipv4.h} and see that it inherits from @code{Object} and
+defines a @code{GetTypeId}. Thus the @code{Object} for which you can
+@code{GetObject} is really the @code{Ipv4 Object}.
+
+Returning to some real @command{ns-3} example code, lets take a look at
+@code{examples/simple-point-to-point.cc}. You will find the following
+code in this file:
+
+@verbatim
+ Ptr<Node> n0 = CreateObject<InternetNode> ();
+ ...
+ Ptr<Ipv4> ipv4;
+ ipv4 = n0->GetObject<Ipv4> ();
+ ipv4->SetDefaultRoute (Ipv4Address (``10.1.1.2''), 1);
+@end verbatim
+
+@cindex InternetNode
+@cindex Node
+@cindex Object
+@cindex GetObject
+The first line creates an @code{InternetNode} implementation object and casts
+the resulting smart pointer to a @code{Node} as we have discussed extensively.
+The next line shown declares a smart pointer to an @code{Ipv4 Object}. We
+then do a @code{GetObject} on the @code{Node} looking for the
+@code{Ipv4 Object}. You know since you've read every line of this tutorial
+in detail exactly how that @code{Ipv4 Object} got into every @code{Node}. You
+know that the @code{GetObject} will return a smart pointer to its aggregated
+@code{Ipv4} Interface. Once we have the @code{Ipv4} smart pointer, we simply
+use it as if it were any other C++ object. The last line shows this by
+setting the default route for the node.
+
+@section Caveats
+There are a few things that you should remember but which may not be
+immediately obvious.
+
+@subsection Ns-3 Objects are Associated with Classes not C++ objects
+@cindex Object
+@cindex GetObject
+@cindex iterate
+@cindex aggregation
+@cindex GetNDevices
+Okay, you can see some of the problems with the terminology popping up again.
+We are reminding you that when you do a GetObject you are providing the key
+to the lookup by giving a class name and not anything that is unique to a
+C++ object.
+
+You cannot add more than one @code{Object} of a given type (class name) to an
+aggregation. If you need to contain a number of @code{Objects} of the same
+type in the same aggregation, you will need to provide a separate container
+over which you can iterate. For example, the @code{Node} class provides
+methods,
+
+@verbatim
+ uint32_t GetNDevices (void) const;
+ Ptr<NetDevice> GetDevice (uint32_t index) const;
+@end verbatim
+
+that are used iterate over the multiple @code{NetDevice} @code{Objects}
+associated with it.
+
+@emph{Remember: Object types do not identify objects.}
+
+@subsection Dont use GetObject to Check Your Own Type.
+@cindex GetObject
+It is tempting to use @code{GetObject} as a form of runtime type
+information. Dont do it. You have no control over what @emph{other}
+object may be added to your aggregation. Someone else may have
+appropriated (reimplemented) your type and aggregated themselves onto the
+aggregation.
+
+Consider a socket factory implementation. Sockets can be either UDP sockets
+or TCP sockets. A socket factory will have a generic @code{SocketFactory}
+Object and either a UDP specific interface for setting UDP parameters or a
+similar TCP-specific interface.
+
+Consider what might happen if you declared your socket factory as a partially
+abstract base class, and then provided separate implementations for UDP and
+TCP specific methods of this factory in separate concrete classes. Now
+consider what might happen if you used @code{GetObject} in your base class
+to determine if you were a UDP or a TCP factory.
+
+If a factory, say the UDP version, were not aggregated to any other
+@code{Object}, the base class could @code{GetObject} on itself for the
+UDP-specific class name. If the @code{GetObject} succeeded, it could then
+infer that it was a UDP implementation and would then do any UDP-specific
+tasks it could. [Experienced C++ folks are cringing about how
+horrible this design is, but bear with me --- its a simple illustration of
+a specific and perhaps not-too-obvious problem.]
+
+If another factory, say the TCP version, were not aggregated to any other
+Interface, the base class could @code{GetObject} on itself for the UDP-specific
+interface. If this failed, it could then infer that it had a TCP
+implementation and would then do any TCP-specific tasks it could.
+
+Now, what happens when these two working objects are aggregated together by
+some innocent end-user. Since the @code{Objects} are conceptually snapped
+together, the TCP implementation would suddenly begin finding the UDP
+Interface from the other class factory and think it was the UPD implementation.
+
+@emph{Objects should not be used as run-time type information.}
+
+@section Connecting the Dots
+@cindex Object
+@cindex GetObject
+@cindex AggregateObject
+@cindex GetTypeId
+@cindex API
+This may all sound very complicated to you if this is your first exposure to
+these concepts. It may be annoying if I tell you that its really not as hard
+as it sounds. Rest assured that if you take some time, look at and understand
+the examples and write a little test code it will all come together for you.
+Grep around the system for @code{AggregateObject} and @code{GetObject} and
+take a look at how we have used them. This will also give you a good idea of
+what our core @code{Objects} and associated APIs are. If you grep for
+@code{GetTypeId} you will find most, if not all of the @code{Object} API
+interface declarations in the system. The more you see this idiom in
+use, the more comfortable you will be with the idea and the more you will see
+how this addresses the weak base class, swiss army knife base class, and
+fragile base class problems I explained at the beginning.
+
+As I alluded to earlier, the developers had long discussions regarding how to
+make navigating the @code{Object} environment easier. The primary issue was
+how we could make it easier to convey to you, the model writer, that an object
+was an @code{Object}. We originally used similar terminology as Microsoft
+COM and used QueryInterface instead of @code{GetObject}. One suggestion was
+to adopt the convention that classes that implemented Interfaces must begin
+with the letter I. Microsoft does this, as exemplified by the class IUnknown.
+We also toyed with the idea of beginning our header files with ``i-'' as in
+``i-ipv4.h.'' We considered forcing some structure on Interfaces with a pure
+virtual class specification, the names of which begin with an I; and
+corresponding implementations, the names of which begin with a C. This all
+got out of hand fairly quickly.
+
+In the end we decided that we were really discussing issues of programming
+style, and we really could not come up with a strong reason to impose any
+particular solution. No matter what direction we took, we ended up with some
+form of extra confusion or extra complexity somewhere in the system. The
+resulting system is extremely flexible and easy to use. It is, unfortunately,
+sometimes hard to document and talk about.
+
+@cindex Feynman
+If it helps you to think in terms of Microsoft COM and Interfaces, by all means
+do so, just be aware that even though @command{ns-3} @code{Objects} descend
+from COM in some sense, there are subtle differences that may get you lost or
+into trouble. So to paraphrase Feynman one more time,
+
+@quotation
+``@command{Ns-3} @code{Objects} do not behave like COM Components, or Java
+Beans, or CORBA objects, or clouds or weights on springs, or like anything
+that you have ever seen --- they are @command{ns-3} components.''
+@end quotation
+
+Just get very familiar with the @command{ns-3} object model. It is the heart
+of the system and if you do not understand it you will not understand how to
+write an @command{ns-3} model properly.
+
+@c ========================================================================
+@c Doxygen
+@c ========================================================================
+
+@node The-Doxygen-Documentation-System
+@chapter The Doxygen Documentation System
+
+@node How-To-Change-Things
+@chapter How to Change Things
+
+@node How-To-Set-Default-Values
+@chapter How to Set Default Values
+
+@node How-To-Write-A-New-Application
+@chapter How to Write a New Application
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/tutorial/in-process/output.texi Sat Jun 28 19:46:55 2008 -0700
@@ -0,0 +1,462 @@
+
+@c ========================================================================
+@c Simulation Output
+@c ========================================================================
+
+@node Simulation Output
+@chapter Simulation Output
+
+At this point, you should be able to execute any of the built-in
+programs distributed with @command{ns-3}. Next, we will look at
+how to generate and tailor the simulation output, before turning
+to how to modify simulation scripts to do different things.
+
+@node Tracing Basics
+@section Tracing Basics
+
+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 goal of the @command{ns-3} tracing system is to
+provide a structured way to configure the simulator to output results
+in standard or modifiable formats.
+@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 will 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 fundamentally built on the
+concept of separating tracing sources from sinks.
+@enumerate
+@item Trace sources (e.g., provide access to every packet received)
+@item Trace sinks (e.g., print out the packet)
+@item A mechanism to tie together sources and sinks
+@end enumerate
+The rationale for this division is to allow users to attach new
+types of sinks to existing tracing sources, without requiring
+users to edit and recompile the core of the simulator.
+Thus, in the example above, a user could write a new tracing sink
+and attach it to an existing tracing source. What remains to
+be defined is a way for users to find these hooks (tracing sources)
+and attach sinks to them. A new tracing namespace is defined for
+this purpose.
+
+We will first walk through how some pre-defined sources and sinks
+are provided and may be customized with little user effort. We
+return later in this chapter to advanced tracing configuration including
+extending the tracing namespace and creating new tracing sources.
+
+@subsection ASCII tracing
+@cindex ASCII
+For Internet nodes, the ASCII trace wrapper is a wrapper around
+the @command{ns-3} low-level
+tracing system that lets you get access to underlying trace events easily.
+The output of a trace of a simulation run is an ASCII file --- thus the name.
+In the spririt of keeping things simple, you won't be able to control or
+configure the output at this stage.
+
+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. As usual, we need to include the definitions
+related to using ASCII tracing (don't edit any files quite yet):
+
+@verbatim
+ #include "ns3/ascii-trace.h"
+@end verbatim
+
+We then need to add the code to the script to actually enable the ASCII tracing
+code. The following code must be inserted before the call to
+@code{Simulator::Run ();}:
+
+@verbatim
+ AsciiTrace asciitrace ("tutorial.tr");
+ asciitrace.TraceAllQueues ();
+ asciitrace.TraceAllNetDeviceRx ();
+@end verbatim
+
+The first line declares an object of type @code{AsciiTrace} named
+@code{asciitrace} and passes a string parameter to its constructor. This
+parameter is a file name to which all of the trace information will be written.
+The second line, @code{asciitrace.TraceAllQueues ();} asks the trace object to
+arrange that all queue operations (enqueue, dequeue, drop) on the queues
+in all of the nodes of the system be traced. On the receive side,
+@code{asciitrace.TraceAlllNetDeviceRx ()} traces packets received by
+a NetDevice. For those familiar with @command{ns-2}, these are equivalent
+to the popular trace points that log "+", "-", "d", and "r" events.
+
+Try running the following program from the command line:
+@verbatim
+ ./waf --run tutorial-csma-echo-ascii-trace
+@end verbatim
+
+@cindex tutorial.tr
+Just as you have seen previously, you will see some messages from @emph{Waf}
+and then the ``Compilation finished successfully'' message. The
+next message, @code{UDP Echo Simulation} is from the running program. When
+it ran, the program will have created a file named @code{tutorial.tr}.
+Because of the way that Waf works, the file is not created in the local
+directory, it is created at the top-level directory of the repository. So,
+change into the top level directory and take a look at the file
+@code{tutorial.tr} in your favorite editor.
+
+@subsubsection Parsing Ascii Traces
+@cindex parsing ascii traces
+
+This section parses in detail the structure of the ascii tracing
+output. If you find this output format self explanatory (it
+resembles tcpdump output), you may skip to the next
+section on pcap tracing.
+
+@cindex trace event
+There's a lot of information there in a pretty dense form, but the first thing
+to notice is that there are a number of distinct lines in this file. It may
+be difficult to see this clearly unless you widen your windows considerably.
+Each line in the file corresponds to a @emph{trace event}. A trace event
+happens whenever specific conditions happen in the simulation. In this case
+we are tracing events on the @emph{device queue} present in every net device
+on every node in the simulation. The device queue is a queue through which
+every packet destined for a channel must pass --- it is the device
+@emph{transmit} queue. Note that each line in the trace file begins with a
+lone character (has a space after it). This character will have the following
+meaning:
+
+@cindex enqueue
+@cindex dequeue
+@cindex drop
+@itemize @bullet
+@item @code{+}: An enqueue operation occurred on the device queue;
+@item @code{-}: A dequeue operation occurred on the device queue;
+@item @code{d}: A packet was dropped, typically because the queue was full.
+@end itemize
+
+Let's take a more detailed view of the first line. I'll break it down into
+sections (indented for clarity) with a two digit reference number on the
+left side:
+
+@verbatim
+ 00 +
+ 01 2
+ 02 nodeid=0
+ 03 device=0
+ 04 queue-enqueue
+ 05 pkt-uid=9
+ 06 ETHERNET
+ 07 length/type=0x806,
+ 08 source=08:00:2e:00:00:00,
+ 09 destination=ff:ff:ff:ff:ff:ff
+ 10 ARP(request
+ 11 source mac: 08:00:2e:00:00:00
+ 12 source ipv4: 10.1.1.1
+ 13 dest ipv4: 10.1.1.2)
+ 14 ETHERNET fcs=0
+@end verbatim
+
+@cindex trace event
+@cindex simulation time
+The first line of this expanded trace event (reference number 00) is the
+queue operation. We have a @code{+} character, so this corresponds to an
+@emph{enqueue} operation. The second line (reference 01) is the simulation
+time expressed in seconds. You may recall that we asked the
+@code{UdpEchoClient} to start sending packets at two seconds. Here we see
+confirmation that this is, indeed, happening.
+
+@cindex node number
+@cindex net device number
+@cindex smart pointer
+The next lines of the example listing (references 02 and 03) tell us that
+this trace event originated in a given node and net device. Each time a node
+is created it is given an identifying number that monotonically increases from
+zero. Therefore, @code{nodeid=0} means that the node in which the given trace
+event originated is the first node we created. In the case of our script,
+this first node is is the node pointed to by the smart pointer @code{n0}. Not
+too surpsisingly, this is also the node to which we attached the
+@code{UdpEchoClient}. The device number is local to each node, and so the
+device given by @code{device=0} is the first net device that we added to the
+node in question. In our simulation, this corresponds to the
+@code{CsmaNetDevice} we added to node zero (@code{n0}).
+
+@cindex uid
+@cindex unique ID
+@cindex packet
+The next line (reference 04) is a more readable form of the operation code
+seen in the first line --- i.e., the character @code{+} means
+@code{queue-enqueue}. Reference number 05 indicates that the @emph{unique id}
+of the packet being enqueued is @code{9}. The fact that the first packet we
+see has a unique ID of 9 should indicates to you that other things have
+happened in the protocol stack before we got to this point. This will become
+clear momentarily.
+
+@cindex Ethernet
+@cindex MAC address
+Reference items 06 and 14 indicate that this is an Ethernet packet with
+a zero (not computed) checksum (note the indentation to make parsing this
+trace event a little easier). Reference 08 and 09 are the source and
+destination addresses of this packet. The packet is from the MAC address we
+assigned to the node zero net device in the script, and is destined for the
+broadcast address --- this is a broadcast packet.
+
+@cindex Address Resolution Protocol
+@cindex ARP
+@cindex ARP|request
+Reference items 10 through 13 make clear what is happening. This is an ARP
+(Address Resolution Protocol) request for the MAC address of the node on
+which the @code{UdpEchoServer} resides. The protocol stack can't send a UDP
+packet to be echoed until it knows (resolves) the MAC address; and this trace
+event corresponds to an ARP request being queued for transmission to the local
+network. The next line in the trace file (partially expanded),
+
+@verbatim
+ 00 -
+ 01 2
+ 02 nodeid=0
+ 03 device=0
+ 04 queue-dequeue
+ 05 pkt-uid=9
+ ...
+@end verbatim
+
+shows the (same) ARP request packet being dequeued from the device queue by
+the net device and (implicitly) being sent down the channel to the broadcast
+MAC address. We are not tracing net device reception events so we don't
+actually see all of the net devices receiving the broadcast packet. We do,
+however see the following in the third line of the trace file:
+
+@verbatim
+ 00 +
+ 01 2.00207
+ 02 nodeid=1
+ 03 device=0
+ 04 queue-enqueue
+ 05 pkt-uid=10
+ 06 ETHERNET
+ 07 length/type=0x806,
+ 08 source=08:00:2e:00:00:01,
+ 09 destination=08:00:2e:00:00:00,
+ 10 ARP(reply
+ 11 source mac: 08:00:2e:00:00:01
+ 12 source ipv4: 10.1.1.2
+ 13 dest mac: 08:00:2e:00:00:00
+ 14 dest ipv4: 10.1.1.1)
+ 15 ETHERNET fcs=0
+@end verbatim
+
+@cindex simulation time
+@cindex ARP|response
+Notice that this is a queue-enqueue operation (references 00 and 04) happening
+on node one (reference 02) at simulation time 2.00207 seconds (reference 01).
+Looking at the packet payload (references 10-14) we see that this is an ARP
+reply to the request sent by node one. Note that the simulation time
+(reference 01) is now 2.00207 seconds. This is direct result of the data rate
+(5 mb/s) and latency (2 ms) parameters that we passed to the
+@code{CsmaChannel} when we created it. Clearly the ARP request packet was
+sent over the channel and received approximately 2 ms later by node one. A
+corresponding ARP response packet was created and enqueued on node one's net
+device. It is this enqueue trace event that has being logged.
+
+@cindex queue
+@cindex queue|transmit
+@cindex echo
+Given the current state of affairs, the next thing you may expect to see is
+this ARP request being received by node zero, but remember we are only looking
+at trace events on the device @emph{transmit} queue. The reception of the ARP
+response by node zero will not directly trigger any trace event in this case,
+but it will enable the protocol stack to continue what it was originally doing
+(trying to send an echo packet). Thus, the next line we see in the trace file
+(@code{tutorial.tr}) is the first UDP echo packet being sent to the net device.
+
+@verbatim
+ 00 +
+ 01 2.00415
+ 02 nodeid=0
+ 03 device=0
+ 04 queue-enqueue
+ 05 pkt-uid=7
+ 06 ETHERNET
+ 07 length/type=0x800,
+ 08 source=08:00:2e:00:00:00,
+ 09 destination=08:00:2e:00:00:01
+ 10 IPV4(
+ 11 tos 0x0
+ 12 ttl 64
+ 13 id 0
+ 14 offset 0
+ 15 flags [none]
+ 16 length: 1052) 10.1.1.1 > 10.1.1.2
+ 17 UDP(length: 1032)
+ 18 49153 > 7
+ 19 DATA (length 1024)
+ 20 ETHERNET fcs=0
+@end verbatim
+
+@cindex simulation time
+@cindex echo
+@cindex ARP
+@cindex ARP|request
+@cindex ARP|response
+@cindex IP
+@cindex Ipv4
+I won't go into too much detail about this packet, but I will point out a
+few key items in the trace. First, the packet was enqueued at simulation time
+of 2.00415 seconds. This time reflects the fact that the echo client
+application started at 2. seconds and there were two ARP packets transmitted
+across the network (two milliseconds + data transmission time each way). The
+packet unique identifier (reference 05) is 7. Notice that this is a lower
+number than the ARP request packet, which had a unique ID of 9. This tells
+us that the UDP packet was actually created before the ARP request packet ---
+which makes perfect sense since it was the attempt to send packet 7 that
+triggered sending the ARP request packet 9. Note that this an Ethernet
+packet (reference 06) like all other packets in this simulation, however this
+particular packet carries an IPV4 payload and therefore has an IP version 4
+header (indicated by references 10-16). This Ipv4 in turn contains a UDP
+header (references 17, 18) and finally 1024 bytes of data (reference 20).
+Clearly, this is the UDP echo packet emitted by the
+@code{UdpEchoClient Application}.
+
+The next trace event is an ARP request from node one. We can infer that node
+one has received the UDP echo packet and the @code{UdpEchoServer Application}
+on that node has turned the packet around. Just as node zero needed to ARP
+for the MAC address of node one, now node one must ARP for the MAC address of
+node zero. We see the ARP request enqueued on the transmit queue of node one;
+then we see the ARP request dequeued from the tranmit queue of node one (and
+implicitly transmitted to node zero). Then we see an ARP response enqueued
+on the transmit queue of node zero; and finally the ARP response dequeued (and
+implicitly transmitted back to node one).
+
+This exchange is summarized in the following trace event excerpts,
+
+@verbatim
+ + 2.00786 nodeid=1 ... ARP(request ...
+ - 2.00786 nodeid=1 ... ARP(request ...
+ + 2.00994 nodeid=0 ... ARP(reply ...
+ - 2.00994 nodeid=0 ... ARP(reply ...
+@end verbatim
+
+The final two trace events in the @code{tutorial.tr} file correspond to the
+echoed packet being enqueued for transmission on the net device for node one,
+and that packet being dequeued (and implicitly transmitted back to node zero).
+
+@cindex AsciiTrace!TraceAllNetDeviceRx
+@cindex ARP!request
+If you look at the trace file (@code{tutorial.tr}) you will also see some
+entries with an @code{r} event, indicating a
+@emph{receive} trace event. Recall that the first packet sent on the network
+was a broadcast ARP request. We should then see all four nodes receive a
+copy of this request. This is the case, as the first four receive trace
+events are,
+
+@verbatim
+ r 2.00207 nodeid=0 device=0 dev-rx pkt-uid=9 ARP(request ...
+ r 2.00207 nodeid=1 device=0 dev-rx pkt-uid=9 ARP(request ...
+ r 2.00207 nodeid=2 device=0 dev-rx pkt-uid=9 ARP(request ...
+ r 2.00207 nodeid=3 device=0 dev-rx pkt-uid=9 ARP(request ...
+@end verbatim
+
+@cindex unique ID
+You can see that a copy of the broadcast packet with unique ID 9 was received
+by the net devices on nodes 0, 1, 2 and 3. We leave it up to you to parse the
+rest of the trace file and understand the remaining reception events.
+
+@subsection PCAP Trace Wrapper
+@cindex pcap
+@cindex Wireshark
+The @command{ns-3} @emph{pcap trace wrapper} is used to create trace files in
+@code{.pcap} format. The acronym pcap (usually written in lower case) stands
+for @emph{p}acket @emph{cap}ture, and is actually an API that includes the
+definition of a @code{.pcap} file format. The most popular program that can
+read and display this format is Wireshark (formerly called Ethereal).
+However, there are many traffic trace analyzers that use this packet
+format, including X, Y, and Z. We encourage users to exploit the
+many tools available for analyzing pcap traces; below, we show how
+tcpdump and Wireshark can be used..
+
+@cindex tutorial-csma-echo-ascii-trace.cc
+@cindex tutorial-csma-echo-pcap-trace.cc
+The code used to enable pcap tracing is similar to that for ASCII tracing.
+We have provided another file, @code{tutorial-csma-echo-pcap-trace.cc} that
+uses the pcap trace wrapper. We have added the code to include the pcap
+trace wrapper defintions:
+
+@verbatim
+ #include "ns3/pcap-trace.h"
+@end verbatim
+
+And then added the following code below the AsciiTrace methods:
+
+@cindex PcapTrace
+@cindex PcapTrace!TraceAllIp
+@verbatim
+ PcapTrace pcaptrace ("tutorial.pcap");
+ pcaptrace.TraceAllIp ();
+@end verbatim
+
+The first line of the code immediately above declares an object of type
+@code{PcapTrace} named @code{pcaptrace} and passes a string parameter to its
+constructor. This object is used to hide the details of the actual tracing
+subsystem. The parameter is a base file name from which the actual trace file
+names will be built. The second line of code tells the @code{PcamTrace}
+object to trace all IP activity in all of the nodes present in the simulation.
+
+@cindex interface index
+Trace files are not created until trace activity is detected. Each file name
+is composed of the base file name, followed by a @code{'-'}, a node id followed
+by a @code{'-}', and an IP interface index. You will soon see a file named
+@code{tutorial.pcap-0-1}, for example. This will be the trace file generated
+as events are detected on node zero, interface index one. N.B. Interface
+indices are different that net device indices --- interface index zero
+corresponds to the loopback interface and interface index one corresponds to
+the first net device you added to a node.
+
+You may run the new program just like all of the others so far:
+
+@cindex Waf
+@verbatim
+ ./waf --run tutorial-csma-echo-pcap-trace
+@end verbatim
+
+If you look at the top level directory of your distribution, you should now
+see three log files: @code{tutorial.tr} is the ASCII trace file we have
+previously examined. @code{tutorial.pcap-0-1} and @code{tutorial.pcap-1-1}
+are the new pcap files we just generated. There will not be files
+corresponding to nodes two and three since we have not sent any IP packets to
+those nodes.
+
+@subsubsection Reading output with tcpdump
+@cindex tcpdump
+
+@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/}.
+
+If you have Wireshark available, you can open each of the trace files and
+display the contents as if you had captured the packets using a
+@emph{packet sniffer}. Note that only IP packets are traced using this
+wrapper, so you will not see the ARP exchanges that were logged when using
+the ASCII trace wrapper. You are encouraged to take a look at the contents
+of these pcap files using your favorite pcap software (or Wireshark).
+
+@node Advanced Tracing
+@section Advanced Tracing
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/tutorial/in-process/statistics.texi Sat Jun 28 19:46:55 2008 -0700
@@ -0,0 +1,9 @@
+@node Statistics
+@chapter Statistics
+@anchor{chap:Statistics}
+
+ns-3 does not presently have support for statistics (automatically generated
+statistical output). This is planned
+for development later in 2008. If you are interested in contributing,
+please see @uref{http://www.nsnam.org/wiki/index.php/Suggested_Projects,,our suggested projects page} or contact the ns-developers
+list.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/tutorial/in-process/troubleshoot.texi Sat Jun 28 19:46:55 2008 -0700
@@ -0,0 +1,82 @@
+@node Troubleshooting
+@chapter Troubleshooting
+
+This chapter posts some information about possibly common errors in building
+or running ns-3 programs.
+
+Please note that the wiki (@uref{http://www.nsnam.org/wiki/index.php/Troubleshooting}) may have contributed items.
+
+@node Build errors
+@section Build errors
+
+@node Run-time errors
+@section Run-time errors
+
+Sometimes, errors can occur with a program after a successful build. These
+are run-time errors, and can commonly occur when memory is corrupted or
+pointer values are unexpectedly null.
+
+Here is an example of what might occur:
+
+@verbatim
+ns-old:~/ns-3-nsc$ ./waf --run tcp-point-to-point
+Entering directory `/home/tomh/ns-3-nsc/build'
+Compilation finished successfully
+Command ['/home/tomh/ns-3-nsc/build/debug/examples/tcp-point-to-point'] exited with code -11
+@end verbatim
+
+The error message says that the program terminated unsuccessfully, but it is
+not clear from this information what might be wrong. To examine more
+closely, try running it under the @uref{http://sources.redhat.com/gdb/,,gdb debugger}:
+
+@verbatim
+ns-old:~/ns-3-nsc$ ./waf --run tcp-point-to-point --command-template="gdb %s"
+Entering directory `/home/tomh/ns-3-nsc/build'
+Compilation finished successfully
+GNU gdb Red Hat Linux (6.3.0.0-1.134.fc5rh)
+Copyright 2004 Free Software Foundation, Inc.
+GDB is free software, covered by the GNU General Public License, and you are
+welcome to change it and/or distribute copies of it under certain conditions.
+Type "show copying" to see the conditions.
+There is absolutely no warranty for GDB. Type "show warranty" for details.
+This GDB was configured as "i386-redhat-linux-gnu"...Using host libthread_db library "/lib/libthread_db.so.1".
+
+(gdb) run
+Starting program: /home/tomh/ns-3-nsc/build/debug/examples/tcp-point-to-point
+Reading symbols from shared object read from target memory...done.
+Loaded system supplied DSO at 0xf5c000
+
+Program received signal SIGSEGV, Segmentation fault.
+0x0804aa12 in main (argc=1, argv=0xbfdfefa4)
+ at ../examples/tcp-point-to-point.cc:136
+136 Ptr<Socket> localSocket = socketFactory->CreateSocket ();
+(gdb) p localSocket
+$1 = {m_ptr = 0x3c5d65}
+(gdb) p socketFactory
+$2 = {m_ptr = 0x0}
+(gdb) quit
+The program is running. Exit anyway? (y or n) y
+@end verbatim
+
+Note first the way the program was invoked-- pass the command to run as
+an argument to the command template "gdb %s".
+
+This tells us that there was an attempt to dereference a null pointer
+socketFactory.
+
+Let's look around line 136 of tcp-point-to-point, as gdb suggests:
+@verbatim
+ Ptr<SocketFactory> socketFactory = n2->GetObject<SocketFactory> (Tcp::iid);
+ Ptr<Socket> localSocket = socketFactory->CreateSocket ();
+ localSocket->Bind ();
+@end verbatim
+
+The culprit here is that the return value of GetObject is not being
+checked and may be null.
+
+Sometimes you may need to use the @uref{http://valgrind.org,,valgrind memory
+checker} for more subtle errors. Again, you invoke the use of valgrind
+similarly:
+@verbatim
+ns-old:~/ns-3-nsc$ ./waf --run tcp-point-to-point --command-template="valgrind %s"
+@end verbatim
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/tutorial/in-process/tutorial.css Sat Jun 28 19:46:55 2008 -0700
@@ -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;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/tutorial/in-process/tutorial.texi Sat Jun 28 19:46:55 2008 -0700
@@ -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
--- a/doc/tutorial/introduction.texi Sat Jun 28 19:39:46 2008 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2034 +0,0 @@
-
-@c ========================================================================
-@c Begin document body here
-@c ========================================================================
-
-@c ========================================================================
-@c Tutorial Goals
-@c ========================================================================
-
-@node Tutorial Goals
-@unnumbered Tutorial Goals
-
-@c This is an unnumbered section, like a preface. Numbering
-@c starts with section 1 (Introduction)
-
-The goal of this ns-3 tutorial is to introduce new users of ns-3 to enough
-of the system to enable them to author simple simulation scripts and extract
-useful information from the simulations. We begin by introducing some of the
-other important resources that are available to those interested in using or
-writing scripts, models and even those interested in making contributions to
-the core ns-3 system. We provide an overview of some of the
-important abstractions, design patterns and idioms used when writing
-ns-3 scripts, and then dig right in by begining to write simulation
-scripts, run them and interpret results.
-
-After completing this tutorial, one should be able to:
-@itemize @bullet
-@item Find documentation resources in the distribution and on the web;
-@item Download and compile the ns-3 system;
-@item Understand the key software conventions of ns-3;
-@item Modify configuration parameters of existing scripts;
-@item Change the simulation output (tracing, logging, statistics);
-@item Extend the simulator to use new objects
-@item Write new ns-3 applications;
-@item See how to port code from ns-2;
-@item ... (more to follow)
-@end itemize
-
-@c ========================================================================
-@c PART: Introduction
-@c ========================================================================
-@c The below chapters are under the major heading "Introduction"
-@c This is similar to the Latex \part command
-@c
-@c ========================================================================
-@c Overview
-@c ========================================================================
-@node Overview
-@chapter Overview
-
-@menu
-* For ns-2 users::
-* Contributing::
-* Tutorial organization::
-@end menu
-
-The ns-3 simulator is a discrete-event network
-simulator targeted primarily for research and educational use.
-The @uref{http://www.nsnam.org,,ns-3 project}, started in
-2006, is an open-source project. The goal of the project is to
-build a new network simulator primarily for research and educational use.
-
-Primary documentation for the 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
-
-The purpose of this tutorial is to introduce new ns-3 users to the
-system in a structured way. It is sometimes difficult for new users to
-glean essential information from detailed manuals and to convert this
-information into working simulations. In this tutorial, we will build
-several example simulations, introducing and explaining key concepts and
-features as we go.
-
-As the tutorial unfolds, we will introduce the full ns-3
-documentation
-and provide pointers to source code for those interested in delving deeper
-into the workings of the system.
-
-A few key points are worth noting at the onset:
-@itemize @bullet
-@item ns-3 is not an extension of @uref{http://www.isi.edu/nsnam/ns,,ns-2};
-it is a new
-simulator. The two simulators are both written in C++ but ns-3
-is a new simulator that does not support the ns-2 APIs.
-Some models from ns-2 have already been ported from ns-2
-to ns-3. The project will continue to maintain ns-2 while
-ns-3 is being built, and will study transition and
-integration mechanisms.
-@item ns-3 is open-source, and the project strives to maintain
-an open environment for researchers to contribute and share their
-software.
-@end itemize
-
-@node For ns-2 users
-@section For ns-2 users
-
-For those familiar with ns-2, the most visible outward change
-when moving to ns-3 is the choice of scripting language.
-ns-2 is typically scripted in Tcl and results of simulations can
-be visualized using the Network Animator @command{nam}. In
-ns-3 there is currently no visualization module, and Python
-bindings have been developed (Tcl bindings have been prototyped
-using @uref{http://www.swig.org,,SWIG}, but are not supported by the
-current development team).
-In this tutorial, we will concentrate on
-scripting directly in C++ and interpreting results via trace files.
-
-But there are similarities as well (both, for example, are based
-on C++ objects, and some code from ns-2 has already been ported
-to ns-3). We will try to highlight differences between ns-2 and ns-3
-as we proceed in this tutorial.
-
-@node Contributing
-@section Contributing
-
-@cindex software configuration management
-ns-3 is a research and educational simulator, by and for the
-research community. It will rely on the ongoing contributions of
-the community to develop new models, debug or maintain
-existing ones, and share results. There are a few policies
-that we hope will encourage people to contribute to ns-3 like they
-have for ns-2:
-@itemize @bullet
-@item open source licensing based on GNU GPLv2 compatibility
-@item @uref{http://www.nsnam.org/wiki/index.php,,wiki}
-@item @uref{http://www.nsnam.org/wiki/index.php/Contributed_Code,,Contributed Code} page, similar to ns-2's popular
-@uref{http://nsnam.isi.edu/nsnam/index.php/Contributed_Code,,Contributed Code}
-page
-@item @code{src/contrib} directory (we will host your contributed code)
-@item open @uref{http://www.nsnam.org/bugzilla,,bug tracker}
-@item ns-3 developers will gladly help potential contributors to get
-started with the simulator (please contact @uref{http://www.nsnam.org/people.html,,one of us})
-@end itemize
-
-If you are an ns user, please consider to provide your feedback,
-bug fixes, or code to the project.
-
-@node Tutorial organization
-@section Tutorial organization
-
-The tutorial assumes that new users might follow a path such as follows:
-
-@itemize @bullet
-@item browse the source code and documentation, to get a feel for
-the simulator and what it might be like to handle;
-@item try to download and build a copy;
-@item try to run a few sample programs, and perhaps change some configurations;
-@item look at simulation output, and try to adjust it
-@item study the software architecture of the system, to consider hacking it or
-extending it;
-@item write new models or port existing code to ns-3, and eventually post those
-models back to the community.
-@end itemize
-
-As a result, we have tried to organize the tutorial along the above
-broad sequences of events.
-
-@c ========================================================================
-@c Browsing ns-3
-@c ========================================================================
-
-@node Browsing
-@chapter Browsing ns-3
-
-@menu
-* Source code::
-* Doxygen::
-* Other documentation::
-@end menu
-
-@node Source code
-@section Source code
-
-The most recent code can be browsed on our web server at the following link:
-@uref{http://code.nsnam.org/?sort=lastchange}. If you click on the bold
-repository names on the left of the page, you will see changelogs for
-these repositories, and links to the @emph{manifest}. From the manifest
-links, one can browse the source tree.
-
-The top-level directory will look something like:
-@verbatim
- AUTHORS RELEASE_NOTES examples/ src/ waf*
- LICENSE VERSION ns3/ tutorial/ waf.bat*
- README doc/ samples/ utils/ wscript
-@end verbatim
-The source code is mainly in the @code{src} directory. Example
-scripts are in the @code{examples} directory. Both are good directories
-to start browsing some code.
-
-For ns-2 users, who may be familiar with the @code{simple.tcl} example script
-in the ns-2 documentation, an analogous script is found in
-@code{examples/simple-point-to-point.cc} with a Python equivalent found
-in @emph{(pending Python merge)}.
-
-@node Doxygen
-@section Doxygen
-
-We document all of APIs using @uref{http://www.stack.nl/~dimitri/doxygen/,,Doxygen}. Current builds of this documentation are available at:
-@uref{http://www.nsnam.org/doxygen/index.html}, which are worth an initial
-look.
-
-@node Other documentation
-@section Other documentation
-
-See: @uref{http://www.nsnam.org/documents.html}.
-
-@c ========================================================================
-@c Resources
-@c ========================================================================
-
-@node Resources
-@chapter Resources
-
-@menu
-* The-Web::
-* Mercurial::
-* Waf::
-* Environment-Idioms-Design-Patterns::
-* Socket-Programming::
-@end menu
-
-@node The-Web
-@section The Web
-
-@cindex www.nsnam.org
-There are several important resources of which any ns-3 user must be
-aware. The main web site is located at @uref{http://www.nsnam.org}
-and provides access to basic information about the ns-3 system.
-Detailed documentation is available through the main web site at
-@uref{http://www.nsnam.org/documents.html}.
-
-@cindex documentation
-@cindex architecture
-You can find documents relating to the system architecture from this page,
-and also gain access to the detailed software documentation. The software
-system is documented in great detail using
-@uref{http://www.stack.nl/~dimitri/doxygen/,,Doxygen}. There is a Wiki that
-complements the main ns-3 web site which you will find at
-@uref{http://www.nsnam.org/wiki/}.
-
-You will find user and developer FAQs there as well as troubleshooting guides,
-third-party contributed code, papers, etc. The source code may be found
-and browsed at @uref{http://code.nsnam.org/}.
-
-@cindex repository!ns-3-dev
-@cindex repository!releases
-There you will find the current development tree in the repository named
-@code{ns-3-dev}. Past releases and experimental repositories of the core
-developers may also be found there.
-
-@node Mercurial
-@section Mercurial
-
-Complex software systems need some way to manage the organization and
-changes to the underlying code and documentation. There are many ways to
-perform this feat, and you may have heard of some of the systems that are
-currently used to do this. The Concurrent Version System (CVS) is probably
-the most well known.
-
-@cindex software configuration management
-@cindex Mercurial
-The ns-3 project uses Mercurial as its source code management system.
-Although you do not need to know much about Mercurial in order to complete
-this tutorial, we recommend becoming familiar with Mercurial and using it
-to access the source code. Mercurial has a web site at
-@uref{http://www.selenic.com/mercurial/},
-from which you can get binary or source releases of this Software
-Configuration Management (SCM) system. Selenic (the developer of Mercurial)
-also provides a tutorial at
-@uref{http://www.selenic.com/mercurial/wiki/index.cgi/Tutorial/},
-and a QuickStart guide at
-@uref{http://www.selenic.com/mercurial/wiki/index.cgi/QuickStart/}.
-
-You can also find vital information about using Mercurial and ns-3
-on the main ns-3 web site.
-
-@node Waf
-@section Waf
-
-@cindex Waf
-@cindex make
-@cindex build
-Once you have source code downloaded to your local system, you will need
-to compile that source to produce usable programs. Just as in the case of
-source code management, there are many tools available to perform this
-function. Probably the most famous of these tools is @code{make}. Along
-with being the most famous, @code{make} is probably the most difficult to
-use in a very large and highly configurable system. Because of this, many
-alternatives have been developed. Recently these systems have been developed
-using the Python language.
-
-The build system @code{Waf} is used on the ns-3 project. It is one
-of the new generation of Python-based build systems. You will not need to
-understand any Python to build the existing ns-3 system, and will
-only have to understand a tiny and intuitively obvious subset of Python in
-order to extend the system in most cases.
-
-For those interested in the gory details of Waf, the main web site can be
-found at @uref{http://freehackers.org/\~tnagy/waf.html}.
-
-@node Environment-Idioms-Design-Patterns
-@section Environment, Idioms, and Design Patterns
-
-@cindex C++
-As mentioned above, scripting in ns-3 is done in C++. A working
-knowledge of C++ and object-oriented concepts is assumed in this document.
-We will take some time to review some of the more advanced concepts or
-possibly unfamiliar language features, idioms and design patterns as they
-appear. We don't want this tutorial to devolve into a C++ tutorial, though,
-so we do expect a basic command of the language. There are an almost
-unimaginable number of sources of information on C++ available on the web or
-in print.
-
-If you are new to C++, you may want to find a tutorial- or cookbook-based
-book or web site and work through at least the basic features of the language
-before proceeding.
-
-@subsection Environment
-
-@cindex toolchain
-@cindex GNU
-The ns-3 system uses the GNU ``toolchain'' for development.
-A software toolchain is the set of programming tools available in the given
-environment. For a quick review of what is included in the GNU toolchain see,
-@uref{http://en.wikipedia.org/wiki/GNU_toolchain}.
-
-@cindex Linux
-Typically an ns-3 author will work in Linux or a Linux-like
-environment. For those running under Windows, there do exist environments
-which simulate the Linux environment to various degrees. The ns-3
-project supports development in the Cygwin and the MinGW environments for
-these users. See @uref{http://www.cygwin.com/} and
-@uref{http://www.mingw.org/} for details on downloading and using these
-systems. Cygwin provides many of the popular Linux system commands.
-It can, however, sometimes be problematic due to the way it
-actually does its emulation, and sometimes interactions with other Windows
-software can cause problems.
-
-@cindex Cygwin
-@cindex MinGW
-If you do use Cygwin or MinGW; and use Logitech products, we will save you
-quite a bit of heartburn right off the bat and encourage you to take a look
-at the @uref{http://www.mingw.org/MinGWiki/index.php/FAQ,,MinGW FAQ}.
-
-@cindex Logitech
-Search for ``Logitech'' and read the FAQ entry, ``why does make often
-crash creating a sh.exe.stackdump file when I try to compile my source code.''
-Believe it or not, the @code{Logitech Process Monitor} insinuates itself into
-every DLL in the system when it is running. It can cause your Cygwin or
-MinGW DLLs to die in mysterious ways and often prevents debuggers from
-running. Beware of Logitech.
-
-@subsection Idioms and Design Patterns
-
-@cindex idiom
-In any system, there are a number of problems to be solved that happen
-repeatedly. Often the solutions to these problems can be generalized and
-applied in a similar way across the system. These solutions are called
-Design Patterns. The ns-3 system relies on several classic design
-patterns.
-
-@cindex design pattern
-Also, in any language, there are constructs that, while they aren't part of the
-language per se, are commonly found and useful. For example, at the lowest
-level a C programmer should be able to immediately recognize the purpose and
-intent of the following code without having to reflect on the details:
-
-@verbatim
- for (;;)
-@end verbatim
-
-These low-level constructs, or idioms, extend upward in complexity, eventually
-becoming implementations of design patterns. As you are exposed to more
-and more of the ns-3 system, you will begin to recognize and be
-comfortable with the C++ implementations (idioms) of several important design
-patterns.
-
-@cindex functor
-@cindex callback
-@cindex smart pointer
-The ns-3 code relies heavily on
-@emph{Generalized Functors, Callbacks,
-Smart Pointers, Singletons, and Object Factories}. Although we will
-not assume any detailed knowledge of the idioms and design patterns used
-in the ns-3
-system, it will be useful for readers who intend to delve deeply into the
-system to understand some important related concepts. We recommend two
-resources: @uref{http://www.amazon.com/Design-Patterns-Object-Oriented-Addison-Wesley-Professional/dp/0201633612/,,Design Patterns: Elements of Reusable Object-Oriented Software, Gamma et. al.} and
-@uref{http://www.amazon.com/exec/obidos/ASIN/0201704315,,Modern C++ Design: Generic Programming and Design Patterns Applied, Alexandrescu}.
-
-Gamma addresses the abstract design patterns, and Alexandrescu addresses the
-C++ idioms you will often see throughout the ns-3 code.
-
-@cindex template
-Almost any use of ns-3 will require some basic knowledge of C++
-templates.
-We will discuss the high-level uses in this tutorial. However, if you venture
-deeply into the source code, you will see fairly heavy use of relatively
-sophisticated C++ templates in some of low-level modules of the system. The
-You don't have to be a template guru to complete this tutorial but if you
-expect to work in ns-3 within the simulation core, you will have to be
-somewhat fluent
-with templates. If you want to truly grok C++ templates we recommend,
-@uref{http://www.amazon.com/Templates-Complete-Guide-David-Vandevoorde/dp/0201734842/,,C++ Templates: The Complete Guide, Vandevoorde and Josuttis}.
-
-@node Socket-Programming
-@section Socket Programming
-
-@cindex sockets
-We will assume a basic facility with the Berkeley Sockets API in the examples
-used in this tutorial. If you are new to sockets, we recommend reviewing the
-API and some common usage cases. For a good overview of programming TCP/IP
-sockets we recommend @uref{http://www.elsevier.com/wps/product/cws_home/680765,,Practical TCP/IP Sockets in C, Donahoo and Calvert}.
-
-There is an associated web site that includes source for the examples in the
-book, which you can find at:
-@uref{http://cs.baylor.edu/~donahoo/practical/CSockets/}.
-
-If you understand the first four chapters of the book (or for those who do
-not have access to a copy of the book, the echo clients and servers shown in
-the website above) you will be in good shape to understand the tutorial.
-There is a similar book on Multicast Sockets,
-@uref{http://www.elsevier.com/wps/product/cws_home/700736,,Multicast Sockets, Makofske and Almeroth}.
-that covers material you may need to understand for the multicast examples.
-
-@c ========================================================================
-@c Downloading and Compiling
-@c ========================================================================
-
-@node Downloading and Compiling
-@chapter Downloading and Compiling
-
-@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/}.
-
-The developers attempt to keep this repository in a consistent, working state
-but it is a development area with unreleased code present, so you may want to
-consider downloading an official release.
-
-There will be a number of released repositories present at code.nsnam.org.
-These repos will have names like ns-3.0.1 --- which referes to release 3.0.1
-of the network simulator (or if you like, release 0.1 of ns-3).
-Since the releases are changing at a rate of one per month, I will stick with
-the more constant ns-3-dev here, but you can replace the string ns-3-dev with
-your choice of release (e.g., ns-3.0.5) below. You can find the latest
-version of the code either by inspection of the repository list or by going
-to the ``Getting Started'' web page and looking for the latest release
-identifier.
-
-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 1513 changesets with 5687 changes to 733 files
- 358 files updated, 0 files merged, 0 files removed, 0 files unresolved
-@end verbatim
-
-After the clone command completes, you should have a directory called
-ns-3-dev under your @code{~/repos} directory, the contents of which should
-look something like the following:
-
-@verbatim
- AUTHORS RELEASE_NOTES examples/ src/ waf*
- LICENSE VERSION ns3/ tutorial/ waf.bat*
- README doc/ samples/ utils/ wscript
-@end verbatim
-
-You are now ready to build the ns-3 distribution.
-
-@section Building
-@cindex Waf!build
-@cindex Waf!configure
-@cindex Waf!debug
-@cindex Waf!compile
-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 program cpp : ok /usr/bin/cpp
- Checking for program ar : ok /usr/bin/ar
- Checking for program ranlib : ok /usr/bin/ranlib
- Checking for compiler could create programs : ok
- Checking for compiler could create shared libs : ok
- Checking for compiler could create static libs : ok
- Checking for flags -Wall : ok
- Checking for flags -O2 : ok
- Checking for flags -g -DDEBUG : ok
- Checking for flags -g3 -O0 -DDEBUG : ok
- Checking for g++ : ok
- Checking for header stdlib.h : ok
- Checking for header stdlib.h : ok
- Checking for header signal.h : ok
- Checking for high precision time implementation: 128-bit integer
- Checking for header stdint.h : ok
- Checking for header inttypes.h : ok
- Checking for header sys/inttypes.h : not found
- Configuration finished successfully; project is now ready to build.
- ~/repos/ns-3-dev >
-@end verbatim
-
-The build system is now configured and you can build the debug versions of
-the 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
-
-and you will see a number of software unit tests subsequently execute.
-
-@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.}
-
-@c ========================================================================
-@c Some Prerequisites
-@c ========================================================================
-
-@node Some-Prerequisites
-@chapter Some Prerequisites
-
-The first thing we need to do before actually starting to code is to explain
-a few core concepts, abstractions and idioms in the system. Much of this may
-appear transparently obvious to some, but we recommend taking the time to read
-through this chapter just to ensure you are starting on a firm foundation.
-
-@section Abstractions
-
-In this section, we'll review some terms that are commonly used in
-networking, but have a specific meaning in 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
-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 a @code{NetDevice} to a @code{Node}, and a @code{NetDevice}
-to a @code{Channel} is such a common task in ns-3 we provide what we
-call @emph{topology helpers} to make this as easy as possible. Topology
-helpers perform much of the dirty work of creating and connecting net devices.
-For example, it may take several distinct method calls to create a NetDevice,
-add a MAC address, connect the net device to a @code{Node} and configure
-the protocol stack, and then connect the @code{NetDevice} to a @code{Channel}.
-We use topology helper functions to compose those distinct operations into
-an easy to use model.
-
-Topology helper functions use the abstractions (described above) of Network
-Interface Cards and Cables. When you think of adding a new kind of network,
-you may think of going out to the local computer retailer and buying a kit.
-This kit might include a nework cable and some number of peripheral cards and
-thier associated software drivers. You can think of topology helpers in
-roughly the same way. Instead of buying a kit for a given type of network,
-you will use a topology helper class for a given type of network, to accomplish
-the equivalent of installing the network ``kit.''
-
-@section Important Idioms
-Now that we have identified that there are C++ classes in the system called
-@code{Node} and @code{InternetNode}, we need to understand how to bring
-objects of these classes into existance, and manage their lifetimes. Let's
-examine this in some detail here.
-
-@cindex InternetNode
-@cindex CreateObject
-@cindex Ptr
-In ns-3, if we want to create an @code{InternetNode} in a
-script, we will
-typically do something like the following example:
-
-@verbatim
- Ptr<Node> p = CreateObject<InternetNode> ();
-@end verbatim
-
-@cindex smart pointer
-To some, it may seem intuitively obvious that we're creating an
-@code{InternetNode} object and assigning responsibility for managing the
-object to a smart pointer named @code{p}. For the rest of us, there may be
-a lot in that line that is unfamiliar, so let's look at what this line means
-in some detail.
-
-@subsection Templates 101
-@cindex template
-If you are familiar with C++ templates, you may skip this section as it is
-just a cursory introduction to function and class templates.
-
-Referring back to the example line of code, reproduced below for your
-convenience, the angle brackets you see in the code indicate that we are
-using C++ @emph{templates}.
-
-@verbatim
- Ptr<Node> p = CreateObject<InternetNode> ();
-@end verbatim
-
-The purpose of templates is to allow a programmer to write one version of code
-that is applicable over multiple types. Some people consider templates to be
-an enhancement of the C preprocessor macro functionality. At some level
-this comparison reveal some similarities, but C++ templates are really
-quite different.
-
-@cindex template!declaration
-@cindex template!definition
-@cindex template!use
-In C++, just as with most language constructs, templates are @emph{declared},
-@emph{defined} and @emph{used}. A declaration of a template might look
-something like,
-
-@verbatim
- template <typename T> T Add (T first, T second);
-@end verbatim
-
-@cindex template!typename
-This line uses the keyword @code{template} followed by a declaration of a
-type name (in this case @code{T}) in angle brackets. The angle brackets
-should indicate to you that a template is being declared, defined or used.
-The type name @code{T} can be thought of as a string that will be substitited
-during the use phase of the template. For example, the @code{T} may be
-replaced by the word @code{int}. It is this substitution that leads people
-to compare templates with macros.
-
-Without going into too much more detail, this snippet declares that a piece
-of code exists that will be able to call a function @code{Add} that will
-add arbitrary types together. The @code{T} will be eventually replaced by
-a C++ data type name. For example,
-
-@verbatim
- T Add (T first, T second);
-@end verbatim
-
-might eventually become
-
-@verbatim
- int Add (int first, int second);
-@end verbatim
-
-If the template has been declared, we need to @emph{define} what that piece of
-code will actually do. That might look something like,
-
-@verbatim
- template <typename T>
- T Add (T first, T second)
- {
- return first + second;
- }
-@end verbatim
-
-All we've done here is to provide an implementation of the template that
-adds the two variables together and returns the result. Note that this
-implementation works for any type that provides an @code{operator+}.
-
-The puzzle all comes together when you understand that @emph{using} a template
-causes the compiler to automatically instantiate code for a specific function
-according to the given template parameters. You might use the above template
-like,
-
-@verbatim
- int x, y, z;
- z = Add<int> (x, y);
-@end verbatim
-
-@cindex template!instantiate
-When the compiler sees @code{Add<int>} it understands that it needs to make
-sure that code is instantiated (created) to perform the @code{Add} using the
-specified type @code{<int>}. To a first approximation, the compiler will
-replace the typename @code{T} with the specified type @code{int} and
-automagically generate code equivalent to,
-
-@verbatim
- int Add (int first, int second)
- {
- return first + second;
- }
-@end verbatim
-
-A user of the template definition could just as easily have provided a use
-that assigned the type float. This would simply be done like,
-
-@verbatim
- float x, y, z;
- z = Add<float> (x, y);
-@end verbatim
-
-In this case, the compiler would automatically generate code that looked like,
-
-@verbatim
- float Add (float first, float second)
- {
- return first + second;
- }
-@end verbatim
-
-@cindex template!function
-This particular kind of template programming uses what are called
-@emph{function templates}. They are called function templates since you
-are @emph{templating} function declarations and definitions.
-
-@cindex template!class
-Templates can also be used in conjunction with classes, in which case you are
-said to be using, not too surprisingly, @emph{class templates}. The syntax and
-use is similar. To declare a class template you might use something like,
-
-@verbatim
- template <typename T>
- class MyStack
- {
- void Push (T data);
- T Pop (void);
- };
-@end verbatim
-
-The methods can be defined separately in a method similar to function template
-definitions,
-
-@verbatim
- template <typename T> void MyStack<T>::Push (T data)
- {
- ...
- };
-@end verbatim
-
-You can then use the new templated class in the following way,
-
-@verbatim
- int x, y;
-
- MyStack<int> stack;
- stack.Push (x);
- y = stack.Pop ();
-@end verbatim
-
-Similarly to the function template case, the compiler knows that it has to
-automatically generate code to fill out the class and method declarations
-and definitions using the appropriate type specified by @code{<int>}.
-
-@node Smart Pointers 101
-@subsection Smart Pointers 101
-If you are familiar with C++ smart pointers, you may skip this section as it
-is just a cursory introduction to smart pointers and intrusive reference
-counting.
-
-@cindex smart pointer
-Referring back to the example line of code, partially reproduced below for
-your convenience below, the left hand side is the declaration and
-initialization of a class template that implements a @emph{smart pointer}.
-
-@verbatim
- Ptr<Node> p = ...
-@end verbatim
-
-To a first approximation, you can think of @code{Ptr<Node>} as the a new kind
-of declaration of a pointer to a @code{Node} object. The difference is that
-a smart pointer is a user-defined data type (instantiated via a templated
-class) that @emph{simulates} a classical pointer but provides additional
-features. As an aside, you typically pronounce @code{Ptr<Node>} as
-``pooter node'' where pooter rhymes with footer.
-
-@cindex memory management
-One of the most important ``additional feature'' provided by smart pointers is
-automatic memory management. Since you now understand class templates, you
-will understand how the template allows us to write the pointer code once, but
-allows us to point to many different kinds of objects. Later in the tutorial
-you will see variations such as @code{Ptr<Ipv4>} and @code{Ptr<Channel>},
-which are smart pointers to an IP version 4 object and a channel object,
-respectively.
-
-The use of built-in pointers in C and C++ is a major source of bugs. Constant
-allocation of, passing of responsibility for, and deallocation of underlying
-data makes it very likely that errors will occur. In one of these errors,
-the usual problem is that the responsibility for deallocating a memory block
-is misplaced. This may result in a memory leak or a duplicate deallocation.
-Smart pointers try to prevent this kind of problem by working with the
-@emph{scope} and @emph{extent} rules of the language to make memory
-deallocation automatic.
-
-The scope of a variable defines where in a program a given variable may be
-referred to. The extent of a variable defines when in the program's execution
-the variable has a valid value. Consider a simple subroutine that contains a
-smart pointer.
-
-@verbatim
- void SimpleSubroutine (void)
- {
- Ptr<Node> p;
- }
-@end verbatim
-
-@cindex scope
-The variable named @code{p} has a scope limited to the subroutine itself. The
-variable is said to @emph{come into scope} as the subroutine is entered during
-execution. At this time, the constructor of the underlying class is executed
-and a valid variable is available for use. When the subroutine is done
-executing, the variable is said to @emph{go out of scope}. This causes the
-destructor of the underlying class to be executed and the variable no longer
-has a valid value. This is not a problem since it is no longer valid to refer
-to the parameter. Smart pointers take advantage of these defined actions at
-points where variables must be valid and become discardable to determine when
-underlying data can be freed.
-
-@cindex reference counting!intrusive
-The ns-3 smart pointer mechanism uses a mechanism called intrusive
-reference counting to determine when a memory block should be automatically
-deallocated. The term ``intrusive'' means that a reference count (a count of
-variables required to have valid data) is stored in the object being managed
-instead of in a proxy object. This means that each piece of memory managed by
-a ns-3 smart pointer includes a reference count. When a smart
-pointer to a reference counted object is created, this reference count is
-incremented. This indicates that a new variable requires a valid data object
-be present. When a smart pointer to a reference counted object is destroyed
-(for example, when going out of scope) the reference count of the managed
-object is decremented. When the reference count goes to zero it means that
-all smart pointers to the underlying object have gone out of scope and the
-object is no longer needed by any past ``users'' of the object. This in turn
-means that the object can be safely deallocated, and this is done
-automatically for you as the ``last'' smart pointer goes out of scope.
-
-Consider how this might work as you pass a smart pointer to an object down
-a protocol stack. At each level of the stack, you pass the smart pointer
-by value. This causes a copy of the smart pointer to be made, which
-increments the reference count of the underlying object. When the
-@emph{calling} method is done executing, the calling smart pointer goes out of
-scope and the reference count is decremented. This leaves the single smart
-pointer in the @emph{called} method with a reference to the underlying object.
-When the smart pointer in the called method goes out of scope, the destructor
-for the smart pointer is called. The destructor checks the reference count
-of the underlying object and sees that it becomes zero. This indicates that
-the object can be deallocated, and the destructor does so. This results in
-the lifetime management of the underlying object being automatically managed,
-a boon if you have experience with ``manual'' memory management and finding
-memory leaks.
-
-Now, we want to make this feature available as widely as possible to objects
-in the ns-3 system. The basic operations of the smart pointer class
-are the same across any intrusively reference counted object. C++ provides a
-mechanism to achieve this kind of generic behavior --- the template. Let's
-examine the declaration of the smart pointer in more detail. First consider
-the way you might declare and use a built-in pointer. For the sake of
-simplicity, just assume that a C++ object of the class @code{MyClass} exists.
-Further assume that @code{MyClass} provides one method called @code{method}.
-Using built-in pointers, you could do something like the following:
-
-@verbatim
- MyClass *p = ...
- p->method ();
-@end verbatim
-
-@cindex smart pointer
-One of the key design points of smart pointers is that they should simulate
-built-in pointers. In C++ this is done by overloading @code{operator->},
-@code{operator=} and @code{operator*}. To implement a smart pointer we need
-to provide a generic class that implements these operators. This generic
-class should allow operations that appear as if it were a built-in pointer
-to the reference counted object. Typically this is accomplished via a
-relatively simple C++ class template. If you are interested in the details
-of how this may be accomplished, see Alexandrescu for a good treatment,
-
-@cindex template
-Taking the template as given, in order to declare a smart pointer you will
-need to create a smart pointer object and provide the template parameter
-needed to instantiate the required code. This parameter will be the name
-of the reference counted class to which you want to point. The smart
-pointer class overrides @code{operator=} which allows initialization of the
-smart pointer just as if it were a built-in pointer. The end result is that
-you use smart pointers just as if they were built-in pointers:
-
-@verbatim
- SmartPointer<MyClass> p = ...
- p->method ();
-@end verbatim
-
-@node Object Creation
-@subsection Object Creation
-@cindex CreateObject
-On the right hand side of the line of code we're examining (reproduced below
-for convenience) is the creation of an @code{InternetNode} object.
-
-@verbatim
- ... = CreateObject<InternetNode> ();
-@end verbatim
-
-@cindex template!function
-This turns out to be an instance of use of a C++ @emph{function template}. The
-definition of the @code{CreateObject<typename T>()} template calls the new
-operator to create an object of the type T. It then creates a new smart
-pointer of the appropriate type (i.e., @code{Ptr<T>}). This new smart
-pointer is assigned initial responsibility for the new object which has its
-reference count set to one.
-
-Since the underlying creation mechanism is via the @code{new} operator, and
-you can pass parameters to the constructor for an object, we provide several
-templates that you can use for passing parameters to the object constructors.
-If the constructor for the object requires a parameter, you simply pass that
-parameter to the @code{Create} function like this,
-
-@verbatim
- int parm = 1;
- ... = CreateObject<MyClass> (parm);
-@end verbatim
-
-We provide Create templates with up to seven parameters, so you could
-conceivably use the @code{Create} template in situations such as,
-
-@verbatim
- int parm = 1;
- ... = CreateObject<MyClass> (p1, p2, p3, p4, p5, p6, p7);
-@end verbatim
-
-@subsection Type Safety
-Lets take one final look at the now infamous example line of code that we
-have been examining for some time (again reproduced below).
-
-@verbatim
- Ptr<Node> p = CreateObject<InternetNode> ();
-@end verbatim
-
-@cindex smart pointer
-@cindex Node
-@cindex Create
-You may have noticed that the smart pointer on the left hand side of the
-assignment is associated with the type @code{Node} and the @code{Create}
-template on the right hand side creates an @code{InternetNode} object and
-returns a @code{Ptr<InternetNode>} smart pointer. For this assignment of a
-@code{Ptr<InternetNode>} to a @code{Ptr<Node>} to work, there must be some
-kind of type conversion going on.
-
-@cindex implicit conversion
-Many programmers use @code{implicit conversions} without even realizing it
-since they are sometimes so intuitive. For example, in the following code,
-
-@verbatim
- int i = 1;
- double d = 2.;
- if (n == d) ...
-@end verbatim
-
-@cindex standard conversion
-the integer (1) is implicitly converted to a double (1.) before the comparison
-takes place. This conversion is performed using what is known as a C++
-@emph{standard conversion}. There are a number of standard conversions defined
-by the C++ standard. Among them are,
-
-@itemize @bullet
-@item Integral Promotions
-@item Integral Conversions
-@item Floating Conversions
-@item Pointer Conversions
-@item Reference Conversions
-@end itemize
-
-@cindex assignment operator
-@cindex Ptr
-For the case of interest here, we need to know what happens in the
-assignment operator (@code{operator=}) of our smart pointer @code{Ptr<Node>}.
-This operator takes a reference to a @code{Ptr<Node>} and not a reference to
-a @code{Ptr<InternetNode>}. The one situation where this works automatically
-in C++ is if the ``destination'' reference is to a visible, unambiguous base
-class of the ``source'' reference. In this case, the underlying pointer is
-@emph{cast} from one type to the other automatically.
-
-To summarize: The magic happens in the assignment operator. Class
-@code{InternetNode} inherits from class @code{Node}. The reference to the
-@code{InternetNode} object in question is, in essence, a pointer to an
-@code{InternetNode} object. The @code{InternetNode} class inherits from the
-@code{Node} base class in a way that makes @code{Node} visible and unambiguous.
-Therefore, there exists a standard conversion from an @code{InternetNode *}
-to a @code{Node *} and by extension from an @code{InternetNode &} to a
-@code{Node &}. This conversion is applied automatically (and invisibly)
-during paramater passing in the assignment operator we are examining.
-
-@cindex base class
-This is a rather involved way of saying there's an invisible pointer cast
-to a base class happening in the assignment. That means that
-
-@verbatim
- Ptr<Node> p = CreateObject<InternetNode> ();
-@end verbatim
-
-or,
-
-@verbatim
- Ptr<Channel> p = CreateObject<CsmaChannel> ();
-@end verbatim
-
-will work just fine. Of course, if you try something @emph{bad} (TM), like:
-
-@verbatim
- Ptr<Node> p = CreateObject<CsmaChannel> ();
-@end verbatim
-
-the compiler will quite appropriately complain that there is no conversion
-between these completely unrelated objects (CsmaChannel and Node).
-
-@subsection Summary
-Going back to our infamous first line of ns-3 code, we said that if
-we want to create an InternetNode in a script, we will typically do something
-like:
-
-@verbatim
- Ptr<Node> p = CreateObject<InternetNode> ();
-@end verbatim
-
-@cindex Create
-@cindex InternetNode
-@cindex smart pointer
-Now we know that this is really a simple statement. We create an
-@code{InternetNode} object on the heap (indirecly using operator @code{new}
-and passing no parameters to its constructor) and assign responsibility for
-managing the new object's lifetime to a smart pointer. This smart pointer is
-a pointer to a @code{Node} object, so there was a hidden cast from
-@code{InternetNode} to a @code{Node} done via a standard C++ conversion.
-
-This may have been quite a hurdle to get past that first line of code, but
-we have covered quite a few of the important idioms that you'll encounter in
-this tutorial.
-
-@c ========================================================================
-@c A First ns-3 script
-@c ========================================================================
-
-@node A-First-ns-3-Script
-@chapter A First ns-3 script
-@cindex design pattern
-@cindex idiom
-Lets build a simple network using the ns-3 design patterns, idioms,
-classes and helpers we have just looked at. If you downloaded the system as
-was suggested above, you will have a release of ns-3 in a directory
-called @code{repos} under your home directory. Change into that directory,
-where you should see a directory structure something like the following.
-
-@verbatim
- AUTHORS RELEASE_NOTES examples/ src/ waf*
- LICENSE VERSION ns3/ tutorial/ waf.bat*
- README doc/ samples/ utils/ wscript
-@end verbatim
-
-@cindex hello-simulator.cc
-Change into the tutorial directory. You should see a file named
-@code{hello-simulator.cc} located there. Copy this file into one named
-@code{simple.cc}. If you open this new file in your favorite editor you will
-see some copyright information and the following C++ code:
-
-@verbatim
- #include "ns3/log.h"
-
- NS_LOG_COMPONENT_DEFINE ("HelloSimulator");
-
- using namespace ns3;
-
- int
- main (int argc, char *argv[])
- {
- LogComponentEnable ("HelloSimulator", LOG_LEVEL_INFO);
-
- NS_LOG_INFO ("Hello Simulator");
- }
-@end verbatim
-
-This is the ns-3 version of the ubiquitous hello-world program. It
-uses the ns-3 Log module to print ``Hello Simulator'' into the
- standard error output stream.
-
-@cindex logging
-Log components are named objects that provide for controlling the verbosity of
-debugging output in the system. We'll have a lot more to say about logging
-later on, but for now you can just consider the macro @code{NS_LOG_INFO} to be
-a kind of fancy printf to the standard error.
-
-@section A Simple Network
-@cindex InternetNode
-Let's create a simple network of @code{InternetNode} elements. In order to
-actually create an @code{InternetNode}, you will have to include some header
-files. Put the following code after the include statement in @code{simple.cc}.
-
-@verbatim
- #include "ns3/ptr.h"
- #include "ns3/internet-stack.h"
-@end verbatim
-
-@cindex include files
-The ns-3 build system places the core include files it needs into a
-directory called @code{ns-3} and so whenever you need to include one of the
-core files you need to explicitly code this. The file @code{ptr.h} defines
-the generic smart pointer that we use. The file @code{internet-stack.h}
-defines the class InternetNode which, as described above, represents an IP
-version 4-based computing element in the simulator.
-
-So let's create a few new @code{InternetNode}s by adding the following lines
-of code after the call to @code{NS_LOG_INFO} in the simple.cc file right
-after the call to @code{NS_LOG_INFO}.
-
-@verbatim
- Ptr<Node> n0 = CreateObject<InternetNode> ();
- Ptr<Node> n1 = CreateObject<InternetNode> ();
- Ptr<Node> n2 = CreateObject<InternetNode> ();
- Ptr<Node> n3 = CreateObject<InternetNode> ();
-@end verbatim
-
-As we now understand, this will create four @code{InternetNode} objects on
-the heap and create four @code{Ptr<Node>} smart pointer objects on the stack
-to manage them. You should remember that by using the smart pointers you are
-freed from the responsibility to delete the objects you assign to them.
-
-@cindex Channel
-@cindex CsmaChannel
-The next step is to create a channel over which these nodes can communicate.
-Let's use the CsmaChannel and create a local area network that will allow us
-to hook up nodes similarly to an Ethernet.
-
-As usual, we'll need to include the file that provides the appropriate class
-declarations:
-
-@verbatim
- #include "ns3/csma-channel.h"
-@end verbatim
-
-Next, Add the following line of code (typically done after node creation) to
-create a channel with a five megabit per second data rate and a two
-millisecond speed-of-light delay between all nodes. The idiom for creating
-the channel is similar to that of the node, but the actual @code{Create}
-function is hidden from us in the topology code. Observe that we are
-using a Csma topology helper function to free us from the details regarding
-how the Carrier Sense Multiple Access Channel is actually brought into
-existence and initialized.
-
-@verbatim
- Ptr<CsmaChannel> lan =
- CsmaTopology::CreateCsmaChannel (DataRate (5000000), MilliSeconds (2));
-@end verbatim
-
-@cindex idiom!unnamed parameter
-You may be unfamiliar with the @emph{unnamed parameter} idiom used here.
-When added to a list of parameters, the code @code{DataRate (5000000)}
-constructs a DataRate object on the stack using the appropriate constructor.
-The resulting object has no name, and therefore cannot be referenced
-elsewhere, but is passed to the callee method where it has a valid name and
-can be used. This idiom is essentially a shorthand version of the following:
-
-@verbatim
- DataRate rate (5000000);
- Time latency (MilliSeconds (2));
- Ptr<CsmaChannel> lan = CsmaTopology::CreateCsmaChannel (rate, latency);
-@end verbatim
-
-@cindex constructor
-@cindex constructor!Time
-We should pause for a moment and discuss the constructor to the @code{Time}
-data type. There are a number of different constructors for these objects, and
-so there are a number of ways that this initialization could have been done.
-There is a constructor that takes a string argument, consisting of expressions
-using the units @code{s, ms, us, ns, ps} or @code{fs}, so this could have been
-written,
-
-@verbatim
- Time latency ("2ms");
-@end verbatim
-
-There are also helper functions available that create time units (one of these
-was used in the example):
-
-@itemize @bullet
-@item @code{Seconds (double)}
-@item @code{MilliSeconds (uint64_t)}
-@item @code{MicroSeconds (uint64_t)}
-@item @code{NanoSeconds (uint64_t)}
-@item @code{PicoSeconds (uint64_t)}
-@item @code{FemtoSeconds (uint64_t)}
-@end itemize
-
-C++ will attempt to promote parameters appropriately, but you will typically
-see constructions that respect the type corrrectness of the constructor, as
-in @code{Seconds (1.)} and @code{MilliSeconds (2)}. Notice that the code
-@code{Seconds (1)} will work just as well as @code{Seconds (1.)} since the
-integer 1 will be automatically promoted to a double 1. in the former code.
-The converse will not work --- i.e., you cannot write code that says
-@code{MilliSeconds (2.)} since a @emph{type demotion} would be required that
-could lose information and the compiler will not do such things ``behind your
-back.'' Don't be thrown off by this kind of automatic conversion.
-
-@cindex MAC!address
-Okay, now we have code to create four nodes and a local area network. The
-next step is to wire the network together. We do this by adding net devices
-to the node. When we add the net device, we also specify the network to which
-the net device is connected and provide a MAC address appropriate to the
-device and network types. Since we're creating an IP version 4 network using
-a Csma channel, you may expect that we'll be using topology helpers
-appropriate to those types --- the CsmaIpv4Topology helper. As you may expect,
-we'll need to include some files to get the appropriate definitions:
-
-@verbatim
- #include "ns3/mac48-address.h"
- #include "ns3/csma-net-device.h"
- #include "ns3/csma-topology.h"
- #include "ns3/csma-ipv4-topology.h"
-@end verbatim
-
-Now, all that is left is to do the ``wiring'':
-
-@verbatim
- uint32_t nd0 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n0, lan,
- Mac48Address("08:00:2e:00:00:00"));
-@end verbatim
-
-[Note the additional unnamed parameter idiom usage here.]
-
-This code calls the topology helper relating to Csma channels and IP version
-four nodes. It asks to install a Csma net device ``into'' node zero
-(@code{n0}) connecting the device to the channel named (@code{lan}). It also
-assigns a MAC address to the net device. You can add similar lines of code
-connecting the other nodes to the lan (remembering to assign new MAC
-addresses).
-
-@verbatim
- uint32_t nd1 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n1, lan,
- Mac48Address("08:00:2e:00:00:01"));
-
- uint32_t nd2 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n2, lan,
- Mac48Address("08:00:2e:00:00:02"));
-
- uint32_t nd3 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n3, lan,
- Mac48Address("08:00:2e:00:00:03"));
-@end verbatim
-
-@cindex IP!address
-@cindex IP!network mask
-@cindex multihome
-Finally, we need to add IP addresses to our nodes. The pointers to the
-nodes are stored in n0, n1, n2 and n3. We added net devices to each of
-the nodes and remembered the net device index numbers as nd0, nd1, nd2 and
-nd3. You can add multiple net devices to each node resulting in a situation
-similar to a multi-homed host. Each time you add a net device, you will get
-a new index. Since the IP address for a multi-homed host is associated with
-a net device, we need to provide that index (which we have saved) to the
-topology helper. We provide an IP version four address via the ns-3
-class @code{Ipv4Address} which takes a dotted decimal string as a constructor
-parameter. We also provide a network mask using the ns-3 class
-@code{Ipv4Mask} which also takes a dotted decimal string. The code to
-perform the IP address assignment, then, looks like the following:
-
-@verbatim
- CsmaIpv4Topology::AddIpv4Address (n0, nd0, Ipv4Address ("10.1.1.1"),
- Ipv4Mask ("255.255.255.0"));
-
- CsmaIpv4Topology::AddIpv4Address (n1, nd1, Ipv4Address ("10.1.1.2"),
- Ipv4Mask ("255.255.255.0"));
-
- CsmaIpv4Topology::AddIpv4Address (n2, nd2, Ipv4Address ("10.1.1.3"),
- Ipv4Mask ("255.255.255.0"));
-
- CsmaIpv4Topology::AddIpv4Address (n3, nd3, Ipv4Address ("10.1.1.4"),
- Ipv4Mask ("255.255.255.0"));
-@end verbatim
-
-We have now constructed a simulated network. Your code should now look
-something like the following,
-
-@verbatim
- #include "ns3/log.h"
- #include "ns3/ptr.h"
- #include "ns3/internet-stack.h"
- #include "ns3/csma-channel.h"
- #include "ns3/mac48-address.h"
- #include "ns3/csma-net-device.h"
- #include "ns3/csma-topology.h"
- #include "ns3/csma-ipv4-topology.h"
-
- NS_LOG_COMPONENT_DEFINE ("HelloSimulator");
-
- using namespace ns3;
-
- int
- main (int argc, char *argv[])
- {
- LogComponentEnable ("HelloSimulator", LOG_LEVEL_INFO);
-
- NS_LOG_INFO ("Hello Simulator");
-
- Ptr<Node> n0 = CreateObject<InternetNode> ();
- Ptr<Node> n1 = CreateObject<InternetNode> ();
- Ptr<Node> n2 = CreateObject<InternetNode> ();
- Ptr<Node> n3 = CreateObject<InternetNode> ();
-
- Ptr<CsmaChannel> lan =
- CsmaTopology::CreateCsmaChannel (DataRate (5000000), MilliSeconds (2));
-
- uint32_t nd0 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n0, lan,
- Mac48Address("08:00:2e:00:00:00"));
-
- uint32_t nd1 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n1, lan,
- Mac48Address("08:00:2e:00:00:01"));
-
- uint32_t nd2 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n2, lan,
- Mac48Address("08:00:2e:00:00:02"));
-
- uint32_t nd3 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n3, lan,
- Mac48Address("08:00:2e:00:00:03"));
-
- CsmaIpv4Topology::AddIpv4Address (n0, nd0, Ipv4Address ("10.1.1.1"),
- Ipv4Mask ("255.255.255.0"));
-
- CsmaIpv4Topology::AddIpv4Address (n1, nd1, Ipv4Address ("10.1.1.2"),
- Ipv4Mask ("255.255.255.0"));
-
- CsmaIpv4Topology::AddIpv4Address (n2, nd2, Ipv4Address ("10.1.1.3"),
- Ipv4Mask ("255.255.255.0"));
-
- CsmaIpv4Topology::AddIpv4Address (n3, nd3, Ipv4Address ("10.1.1.4"),
- Ipv4Mask ("255.255.255.0"));
- }
-@end verbatim
-
-This script won't actually do anything yet. The next trick will be to
-convince our nodes to try and send some data over the network.
-
-@section Using Applications
-@cindex Create
-As mentioned above, we use @code{Application}s in ns-3 to generate
-the data used to drive simulations. An @code{Application} is added to a
-ns-3 node conceptually just as if you would add an application to a
-computer. When an application is created (using the @code{Create} template)
-we tell the application which @code{Node} it belongs to (and therefore on
-which node it is running) by passing a smart pointer to that @code{Node} in
-the constructor arguments.
-
-@subsection A UDP Echo Client Application
-To use an application, we first have to load the header file in which it is
-defined. For the UDP echo client, this would mean adding the line,
-
-@verbatim
-#include "ns3/udp-echo-client.h"
-@end verbatim
-
-In order to create the UDP echo client application we will need to add the
-following code:
-
-@verbatim
- uint32_t packetSize = 1024;
- uint16_t port = 7;
- uint32_t maxPacketCount = 1;
- Time interPacketInterval = Seconds (1.);
-
- Ptr<UdpEchoClient> client = CreateObject<UdpEchoClient> (n0, "10.1.1.2",
- port, maxPacketCount, interPacketInterval, packetSize);
-@end verbatim
-
-@cindex packet
-The first four lines have broken out the configuration parameters for the
-application as named parameters for clarity. We are telling the application
-to generate 1024 byte packets (@code{packetSize = 1024}); and to send these
-packets to port 7 (@code{port = 7;}). The application is told to send at most
-one packet (@code{maxPacketCount = 1;}); and to delay for one second between
-packet sends (@code{interpacketInterval = Seconds(1.)}) which is not used since
-only one packet is sent. We will defer addressing the type @code{Time} until
-we discuss the simulator engine. For now just understand the semantics are
-to wait for one second.
-
-The code to actually create the @code{UdpEchoClient} application uses the
-same creation idiom as we have used previously. Notice that we have a case
-where the @code{Create} template is used to pass parameters to the constructor
-of the underlying object.
-
-@cindex implicit conversion sequence
-Notice that a string is passed as the second parameter. The formal parameter
-to the constructor of the @code{UdpEchoClient} object is actually an
-@code{Ipv4Address}. We get away with this since C++ allows what are called
-@emph{implicit conversion sequences} to occur between the argument in the
-function call and the corresponding parameter in the function declaration.
-Basically, C++ will try to figure out a way to convert parameters for you
-transparently.
-
-In this case the conversion sequence is based on the constructor for the
-Ipv4Address that takes a @code{char const *} as a parameter. C++ notices
-that @code{"10.1.1.2"} refers to a @code{char const *} and knows that it
-needs to get from there to an @code{Ipv4Address}. The compiler notices that
-there is an @code{Ipv4Address} constructor that takes a @code{char const *}
-and so it uses that constructor transparently to arrange for the conversion.
-
-You therefore have several options for passing this value. You can use an
-explicit named variable as in the following:
-
-@verbatim
- Ipv4Address addr ("10.1.1.2");
- ...
-
- Ptr<UdpEchoClient> client = CreateObject<UdpEchoClient> (n0, addr, port,
- maxPacketCount, interPacketInterval, packetSize);
-@end verbatim
-
-@cindex idiom|unnamed parameter
-You can use the unnamed parameter idiom that we have previously seen:
-
-@verbatim
- Ptr<UdpEchoClient> client = CreateObject<UdpEchoClient> (n0,
- Ipv4Address ("10.1.1.2"), port, maxPacketCount, interPacketInterval,
- packetSize);
-@end verbatim
-
-Or you can rely on implicit conversion sequences as we just saw:
-
-@verbatim
- Ptr<UdpEchoClient> client = CreateObject<UdpEchoClient> (n0, "10.1.1.2",
- port, maxPacketCount, interPacketInterval, packetSize);
-@end verbatim
-
-Which approach to take is a matter of style, really, and you will probably
-see all three approaches taken in the ns-3 code. You should be
-comfortable seeing and using all three methods.
-
-@subsection A UDP Echo Server Application
-As usual, to use the UDP echo server we need to add a line to define the
-application:
-
-@verbatim
-#include "ns3/udp-echo-server.h"
-@end verbatim
-
-In order to create the UDP echo server application we will need to add the
-following code:
-
-@verbatim
- Ptr<UdpEchoServer> server = CreateObject<UdpEchoServer> (n1, port);
-@end verbatim
-
-We only need to tell the application which node to reside on and which port
-to listen on for UDP packets. The code to actually create the
-@code{UdpEchoServer} application uses the now quite familiar ns-3 object
-creation idiom.
-
-@subsection A UDP Echo Client-Server Simulation
-Now we're getting somewhere. Your code should look something like the
-following (let's change the log component name and program banner from
-``Hello Simulator''to something more descriptive while we're at it).
-
-@verbatim
- #include "ns3/log.h"
- #include "ns3/ptr.h"
- #include "ns3/internet-stack.h"
- #include "ns3/csma-channel.h"
- #include "ns3/mac48-address.h"
- #include "ns3/csma-net-device.h"
- #include "ns3/csma-topology.h"
- #include "ns3/csma-ipv4-topology.h"
- #include "ns3/udp-echo-client.h"
- #include "ns3/udp-echo-server.h"
-
- NS_LOG_COMPONENT_DEFINE ("UdpEchoSimulation");
-
- using namespace ns3;
-
- int
- main (int argc, char *argv[])
- {
- LogComponentEnable ("UdpEchoSimulation", LOG_LEVEL_INFO);
-
- NS_LOG_INFO ("UDP Echo Simulation");
-
- Ptr<Node> n0 = CreateObject<InternetNode> ();
- Ptr<Node> n1 = CreateObject<InternetNode> ();
- Ptr<Node> n2 = CreateObject<InternetNode> ();
- Ptr<Node> n3 = CreateObject<InternetNode> ();
-
- Ptr<CsmaChannel> lan =
- CsmaTopology::CreateCsmaChannel (DataRate (5000000), MilliSeconds (2));
-
- uint32_t nd0 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n0, lan,
- Mac48Address("08:00:2e:00:00:00"));
-
- uint32_t nd1 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n1, lan,
- Mac48Address("08:00:2e:00:00:01"));
-
- uint32_t nd2 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n2, lan,
- Mac48Address("08:00:2e:00:00:02"));
-
- uint32_t nd3 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n3, lan,
- Mac48Address("08:00:2e:00:00:03"));
-
- CsmaIpv4Topology::AddIpv4Address (n0, nd0, Ipv4Address ("10.1.1.1"),
- Ipv4Mask ("255.255.255.0"));
-
- CsmaIpv4Topology::AddIpv4Address (n1, nd1, Ipv4Address ("10.1.1.2"),
- Ipv4Mask ("255.255.255.0"));
-
- CsmaIpv4Topology::AddIpv4Address (n2, nd2, Ipv4Address ("10.1.1.3"),
- Ipv4Mask ("255.255.255.0"));
-
- CsmaIpv4Topology::AddIpv4Address (n3, nd3, Ipv4Address ("10.1.1.4"),
- Ipv4Mask ("255.255.255.0"));
-
- uint32_t packetSize = 1024;
- uint16_t port = 7;
- uint32_t maxPacketCount = 1;
- Time interPacketInterval = Seconds (1.);
-
- Ptr<UdpEchoClient> client = CreateObject<UdpEchoClient> (n0, "10.1.1.2",
- port, maxPacketCount, interPacketInterval, packetSize);
-
- Ptr<UdpEchoServer> server = CreateObject<UdpEchoServer> (n1, port);
-
- }
-@end verbatim
-
-@section Using the Simulation Engine
-@cindex model
-@cindex simulation executive
-You could say that the heart of the ns-3 system is the
-@emph{simulation engine} (sometimes called the simulation executive in other
-systems).
-
-In a computer simulation, a computer @emph{model} of a real world @emph{system}
-is constructed. This is typically done to minimize cost since you do not have
-to actually buy, install and maintain physical hardware. In the case of
-ns-3, a model is a representation of a networking component that is
-designed to imitate some number of important behaviors or characteristics of
-an actual component in a real network. A system is a collection of models
-arranged for the purpose of analyzing some behavior.
-
-@section Models
-@cindex CsmaNetDevice
-@cindex CsmaChannel
-@cindex InternetNode
-@cindex NIC
-@cindex CSMA
-We have already encountered several ns-3 models without specifically
-calling them so. The @code{InternetNode}, @code{CsmaNetDevice} and
-@code{CsmaChannel} objects are models of an Internet computing node, a CSMA
-network interface card (NIC), and a network cable able to move data to and
-from other CSMA NICs.
-
-@cindex model
-@cindex CSMA/CD
-It is important to note that the @code{Csma} net devices and the @code{Csma}
-channel do not correspond to any real world hardware that you can actually go
-out and buy. These models implement an approximation, or subset, of the
-behaviors that a real CSMA/CD network would have. In this case, the
-@code{CsmaNetDevice} does not simulate collision detection (CD). It does
-implement carrier sense and performs collision @emph{avoidance} using global
-spatial knowledge available in the channel. This would be impossible in any
-channel residing in our universe.
-
-@cindex Ethernet
-No model will fully implement @emph{all} of the behaviors of a piece of
-hardware. It is important to understand what is being modeled by the
-ns-3 components you are using and what is not. For example, the Csma
-components we use in this tutorial model a highly abstract multiple access
-network that is topologically equivalent to an Ethernet. It is not necessarily
-true that results found in a simulation using the Csma models will apply to
-a real-world Ethernet network. You must understand what behaviors are
-simulated in each of the models before trusting that any results can be
-associated with real-world systems.
-
-@section Time, Events and Callbacks
-@cindex time
-@cindex event
-In a @emph{discrete event simulator} time is not something that @emph{flows},
-nor is it something to be measured --- it is the driving force behind the
-progress of the simulation. Time is progressed forward by the simulation
-engine and anything that happens in the simulation is ultimately caused by
-an @emph{event}. An event is some action in the system that is
-@emph{scheduled} to happen at a certain time by the simulation engine. Time
-does not flow continuously but steps discretely (in possibly large jumps)
-from one scheduled event to another.
-
-@cindex packet
-For example, to start the flow of a packet through the system, one would have
-to schedule an event with the simulation engine @emph{before} the simulation
-was started. This is important since the simulation engine only jumps time
-forward if there is a next event to process. The simulation stops if there
-are no more events, which is equivalent to a state where there is ``nothing
-more to do.'' Before the simulation starts, one schedules driving events in
-terms of absolute time. For example, one could schedule an event to start
-the flow of a first packet at, say, ten simulated seconds. In this case, the
-simulation would start its clock at zero seconds and look for the first event
-in its @emph{event queue}. It would immediately jump time forward by ten
-seconds and @emph{fire} the scheduled event --- that is, make the event happen.
-
-@cindex functor
-@cindex function object
-@cindex callback
-@cindex Callback
-In ns-3 an event is basically a pre-packaged function call called a
-@emph{functor}. Functors are also known as @emph{function objects}, which is
-a more descriptive term --- an object (in the object-oriented programming
-sense) that can be called as if it was a function. Typically one uses a
-functor to implement @emph{deferred execution} of a function or method. The
-most commonly encoutered form of deferred execution is in a @emph{callback}
-from an I/O system. In this case, the goal would be to start an I/O
-operation and return immediately, without having to wait for the operation
-to complete. One asks the I/O subsytem to notify you when an operation is
-complete by calling some function you provide. This provided function is
-known as a callback function. [Imagine calling someone on the telephone and
-asking them to do something for you. You also ask them to @emph{call you back}
-when they are done.] Events in the ns-3 system work conceptually
-the same way, except that instead of an I/O completion driving the process,
-the arrival of some simulated time drives the process. The ns-3
-deferred exectution mechanism is via a class called @code{Callback}.
-
-@cindex Time
-@cindex Callback
-The internal details of the classes representing @code{Time} and
-@code{Callback} abstractions will be introduced as required. We won't see
-events directly for some time, but you should know that they are happening
-``under the sheets'' of the simulations you will be writing.
-
-@section Driving the Simulation
-@cindex Application
-As mentioned previously, time is the driving force behind the progress of
-a ns-3 simulation. Events are scheduled to happen at certain times
-by calling methods of the simulation engine, either directly or indirectly
-through, for example, an @code{Application}.
-
-In order to get the simulation engine set up and running in our code, we must
-first include the language definitions required to describe time- and
-simulator-specific classes:
-
-@verbatim
- #include "ns3/simulator.h"
- #include "ns3/nstime.h"
-@end verbatim
-
-@cindex Application
-As we have seen, we need to ``seed'' the simulation with at least one event.
-In the case of an @code{Application}, a method to do this is provided. This
-method must be implemented by each specialization of the class and we must
-call this method in our script before the simulation starts. We can also
-provide an event (indirectly) to stop the output of the application at a
-certain time. This is done by adding the following lines to our script:
-
-@verbatim
- server->Start(Seconds(1.));
- client->Start(Seconds(2.));
-
- server->Stop (Seconds(10.));
- client->Stop (Seconds(10.));
-@end verbatim
-
-@cindex Application
-@cindex time
-@cindex Time
-@cindex socket
-@cindex event
-In the case of the UdpEchoServer, the call to @code{server->Start ()} gives
-the @code{Application} the chance to schedule an event that will perform the
-usual @emph{sockets} server sequence of socket creation, binding and
-recvfrom (see Donahoo's UDPEchoServer.c).
-
-In the case of the UdpEchoClient, the call to @code{client->Start ()} gives
-the @code{Application} the chance to schedule an event that will perform the
-usual @emph{sockets} client sequence of socket creation, sendto and recvfrom
-(see Donahoo's UDPEchoClient.c).
-
-@cindex event
-Note that the start event for the server is scheduled to happen before the
-start event of the client, just as you would start a server application before
-you would attempt to start a client application in the real world.
-
-@cindex socket!sendto
-The ns-3 equivalent of the call to @code{sendo} in the client will
-schedule (immediately) the transmission of a UDP packet over the just created
-socket. This will cause the packet to percolate down the protocol stack and
-eventually into the channel. The channel will schedule a reception event in
-the net device on the destination node. This event will eventually percolate
-up into the server application. The server application will create a reply
-packet and send it back down its stack and eventually back to the channel.
-The channel will schedule a reception event back in the client and this will
-cause the reply to be sent back up the protocol stack to the client
-application.
-
-The calls to @code{Stop ()} for both applications cause the sockets to be
-torn down and therefore the sending and receiving of packets will be stopped
-irrespective of other application settings (such as max packets and interval
-in the client).
-
-Finally, we need to run the simulation and when the simulation run is complete,
-clean up any resources allocated during the run. This is done by the calling
-the following static methods:
-
-@verbatim
- Simulator::Run ();
- Simulator::Destroy ();
-@end verbatim
-
-We now have the makings of a complete ns-3 network simulation. The
-source code for the script should look like the following:
-
-@verbatim
- #include "ns3/log.h"
- #include "ns3/ptr.h"
- #include "ns3/internet-stack.h"
- #include "ns3/csma-channel.h"
- #include "ns3/mac48-address.h"
- #include "ns3/csma-net-device.h"
- #include "ns3/csma-topology.h"
- #include "ns3/csma-topology.h"
- #include "ns3/csma-ipv4-topology.h"
- #include "ns3/udp-echo-client.h"
- #include "ns3/udp-echo-server.h"
- #include "ns3/simulator.h"
- #include "ns3/nstime.h"
-
- NS_LOG_COMPONENT_DEFINE ("UdpEchoSimulation");
-
- using namespace ns3;
-
- int
- main (int argc, char *argv[])
- {
- LogComponentEnable ("UdpEchoSimulation", LOG_LEVEL_INFO);
-
- NS_LOG_INFO ("UDP Echo Simulation");
-
- Ptr<Node> n0 = CreateObject<InternetNode> ();
- Ptr<Node> n1 = CreateObject<InternetNode> ();
- Ptr<Node> n2 = CreateObject<InternetNode> ();
- Ptr<Node> n3 = CreateObject<InternetNode> ();
-
- Ptr<CsmaChannel> lan =
- CsmaTopology::CreateCsmaChannel (DataRate (5000000), MilliSeconds (2));
-
- uint32_t nd0 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n0, lan,
- Mac48Address("08:00:2e:00:00:00"));
-
- uint32_t nd1 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n1, lan,
- Mac48Address("08:00:2e:00:00:01"));
-
- uint32_t nd2 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n2, lan,
- Mac48Address("08:00:2e:00:00:02"));
-
- uint32_t nd3 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n3, lan,
- Mac48Address("08:00:2e:00:00:03"));
-
- CsmaIpv4Topology::AddIpv4Address (n0, nd0, Ipv4Address ("10.1.1.1"),
- Ipv4Mask ("255.255.255.0"));
-
- CsmaIpv4Topology::AddIpv4Address (n1, nd1, Ipv4Address ("10.1.1.2"),
- Ipv4Mask ("255.255.255.0"));
-
- CsmaIpv4Topology::AddIpv4Address (n2, nd2, Ipv4Address ("10.1.1.3"),
- Ipv4Mask ("255.255.255.0"));
-
- CsmaIpv4Topology::AddIpv4Address (n3, nd3, Ipv4Address ("10.1.1.4"),
- Ipv4Mask ("255.255.255.0"));
-
- uint32_t packetSize = 1024;
- uint16_t port = 7;
- uint32_t maxPacketCount = 1;
- Time interPacketInterval = Seconds (1.);
-
- Ptr<UdpEchoClient> client = CreateObject<UdpEchoClient> (n0, "10.1.1.2",
- port, maxPacketCount, interPacketInterval, packetSize);
-
- Ptr<UdpEchoServer> server = CreateObject<UdpEchoServer> (n1, port);
-
- server->Start(Seconds(1.));
- client->Start(Seconds(2.));
-
- server->Stop (Seconds(10.));
- client->Stop (Seconds(10.));
-
- Simulator::Run ();
- Simulator::Destroy ();
- }
-@end verbatim
-
-@cindex tutorial-csma-echo.cc
-Just to make sure you don't get caught up in debugging typographical errors
-we have provided this source code for you (along with a copyright header) in
-the @code{tutorial} subdirectory of the ns-3 distribution as
-@code{tutorial-csma-echo.cc}. We used this opportunity to do some ``clean up''
-of some of our example cases by passing parameters using implicit conversion
-sequences and removing some of the named parameters. [These were used for
-pedagogic purposes and were not actually necessary.]
-
-@section Building the Script
-@cindex Waf
-C++ is a compiled language, so you know it had to happen. We have to build
-the script before we run it. As mentioned before, we use the Waf build system
-which is Python-based. We have to change gears slightly and switch ourselves
-to Python mode in order to proceed.
-
-In each subdirectory of the ns-3 distribution in which there are
-source files, you will find two files: one will be named @code{waf} and one
-will be named @code{wscript}. The former, @code{waf}, is a link that allows
-one to start the build process from any subdirectory. We can ignore that one.
-The file we need to deal with is @code{wscript}.
-
-@cindex wscript
-Open the file @code{ns-3-dev/tutorial/wscript} in your favorite editor
-[remember I'm assuming that you have the distribution saved in a
-repository under a directory called @code{repos} in you home directory.]
-
-@cindex Python
-You should see the following Python code (after an emacs mode line).
-
-@verbatim
- def build(bld):
- obj = bld.create_ns3_program('hello-simulator')
- obj.source = 'hello-simulator.cc'
-@end verbatim
-
-These are the only instructions required to build a simulation (I told you
-it wasn't going to be too bad). The line with the method
-@code{bld.create_ns3_program} tells the build system to create an object
-file that is a program (executable) named @code{hello-simulator}. The
-following line, with the method @code{obj.source} tells the build system that
-the source file for the program is the file @code{hello-simulator.cc'} in the
-local directory. The required libraries are linked for you for free.
-
-All that needed to be done in order to build the new simulation using the new
-source file was to copy the two lines describing the @code{hello-simulator}
-program and change the names to @code{tutorial-csma-echo}. You can see these
-lines in the @code{wscript} file,
-
-@verbatim
- def build(bld):
- obj = bld.create_ns3_program('hello-simulator')
- obj.source = 'hello-simulator.cc'
-
- obj = bld.create_ns3_program('tutorial-csma-echo')
- obj.source = 'tutorial-csma-echo.cc'
-
- ...
-@end verbatim
-
-When you built the system above, you actually already built this new
-simulation and a number of other examples. Since you have already configured
-@code{Waf} and built the @code{tutorial-csma-echo} script, you can run the
-simulation in the same way as you ran the @code{hello-simulator} script using
-the @code{waf --run} command:
-
-@verbatim
-~/repos/ns-3-dev/tutorial > waf --run tutorial-csma-echo
-Entering directory `~/repos/ns-3-dev/build'
-Compilation finished successfully
-UDP Echo Simulation
-~/repos/ns-3-dev/tutorial >
-@end verbatim
--- a/doc/tutorial/log.texi Sat Jun 28 19:39:46 2008 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +0,0 @@
-@node Logging
-@chapter Logging
-@anchor{chap:Logging}
-
-This chapter is the first in a series of chapters discussing things that
-one can do to modify the input or output of existing ns-3 scripts.
-
-Examples:
-@itemize @bullet
-@item Enable or disable the generation of log messages, with fine granularity
-@item Set default values for configuration values in the system
-@item Generate a report of all configuration values used during a simulation
-run (not yet implemented)
-@item Set or get values of member variables on objects already instantiated
-@item Customizing the tracing output of the script
-@item Generate statistics on (not yet implemented)
-@item Perform a large number of independent runs of the same simulation
-@end itemize
-
-@node Logging Basics
-@section Logging Basics
-
-@node Enabling Log Output
-@section Enabling Log Output
--- a/doc/tutorial/other.texi Sat Jun 28 19:39:46 2008 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2189 +0,0 @@
-@c ========================================================================
-@c Other Network Topologies
-@c ========================================================================
-
-@node Other-network-topologies
-@chapter Other Network Topologies
-@cindex topology
-@cindex Channel
-@cindex NetDevice
-@cindex topology!bus
-@cindex topology!point-to-point
-@cindex PointToPointChannel
-@cindex PointToPointNetDevice
-
-@emph{Network topology} is the study of the arrangement of of the elements
-(in @command{ns-3} represented by the classes @code{Channel} and @code{Node})
-of a network. Two fundamental types of physical topologies are the
-@emph{point-to-point} and @emph{bus} topologies. We have already been exposed
-to the @command{ns-3} channel specialization named @code{CsmaChannel}. This is
-a simulation of a bus network. We also provide a simulation of a
-point-to-point channel with associated net devices. As described previously,
-the associated C++ classes specialize the @command{ns-3} base classes
-@code{NetDevice} and @code{Channel} and are called @code{PointToPointNetDevice}
-and @code{PointToPointChannel} respectively.
-
-We will use combinations of these bus and point-to-point topology elements
-to show how to create several commonly seen network topologies.
-
-@section A Point-to-Point Network
-We're going to take what might be seen as a step backward and look at a simple
-point-to-point network. We will be building the simplest network you can
-imagine. A serial link (point to point) between two computers. When you
-see this point-to-point network, you can think of an RS-422 (or RS-232 for
-you old-timers) cable. This topology is shown below.
-
-@sp 1
-@center @image{figures/pp,,,,png}
-
-@cindex CreateObject
-@cindex InternetNode
-We have provided a file for you in the @code{tutorial}
-directory called @code{tutorial-point-to-point.cc}. You should now be
-familiar enough with the system to pick out fairly easily what has been
-changed. Let's focus on the following lines:
-
-@verbatim
- Ptr<Node> n0 = CreateObject<InternetNode> ();
- Ptr<Node> n1 = CreateObject<InternetNode> ();
-
- Ptr<PointToPointChannel> link = PointToPointTopology::AddPointToPointLink (
- n0, n1, DataRate (38400), MilliSeconds (20));
-
- PointToPointTopology::AddIpv4Addresses (link, n0, "10.1.1.1",
- n1, "10.1.1.2");
-@end verbatim
-
-You can see that we created two @code{InternetNode} objects in the usual way.
-Then, instead of creating a @code{CsmaChannel} we create a
-@code{PointToPointChannel}. This point-to-point channel, which we call
-@code{link}, connects node zero (@code{n0}) and node one (@code{n1}) over a
-simulated link that runs at 38400 bits per second and has a 20 millisecond
-simulated speed-of-light delay. This call also creates appropriate net devices
-and attaches them to nodes zero and one.
-
-We then add IP addresses to the net devices we just created using the topology
-helper @code{AddIpv4Addresses}. Node zero gets the IP address 10.1.1.1 and
-node one gets the IP address 10.1.1.2 assigned.
-
-The alert tutorial user may wonder what the network number or prefix is of
-those IP addresses. The point-to-point topology assumes that you want a
-@code{/30} subnet and assigns an appropriate net mask for you. It then then
-@emph{asserts} that the network numbers of the two net devices match. So there
-is an implicit network mask created down in the topology code that looks like,
-
-@verbatim
- Ipv4Mask netmask("255.255.255.252");
-@end verbatim
-
-The rest of the code you should recognize and understand. We are just going
-to echo one packet across the point-to-point link. You should be now be able
-to build and run this example and to locate and interpret the ASCII trace
-file. This is left as an exercise for you.
-
-The file @code{tutorial-point-to-point.cc} is reproduced here for your
-convenience:
-
-@verbatim
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "ns3/log.h"
-#include "ns3/ptr.h"
-#include "ns3/internet-stack.h"
-#include "ns3/point-to-point-channel.h"
-#include "ns3/mac48-address.h"
-#include "ns3/point-to-point-net-device.h"
-#include "ns3/point-to-point-topology.h"
-#include "ns3/udp-echo-client.h"
-#include "ns3/udp-echo-server.h"
-#include "ns3/simulator.h"
-#include "ns3/nstime.h"
-#include "ns3/ascii-trace.h"
-#include "ns3/pcap-trace.h"
-#include "ns3/global-route-manager.h"
-
-NS_LOG_COMPONENT_DEFINE ("PointToPointSimulation");
-
-using namespace ns3;
-
-// Network topology
-//
-// point to point
-// +--------------+
-// | |
-// n0 n1
-//
-int
-main (int argc, char *argv[])
-{
- LogComponentEnable ("PointToPointSimulation", LOG_LEVEL_INFO);
-
- NS_LOG_INFO ("Point to Point Topology Simulation");
-
- Ptr<Node> n0 = CreateObject<InternetNode> ();
- Ptr<Node> n1 = CreateObject<InternetNode> ();
-
- Ptr<PointToPointChannel> link = PointToPointTopology::AddPointToPointLink (
- n0, n1, DataRate (38400), MilliSeconds (20));
-
- PointToPointTopology::AddIpv4Addresses (link, n0, "10.1.1.1",
- n1, "10.1.1.2");
-
- uint16_t port = 7;
-
- Ptr<UdpEchoClient> client = CreateObject<UdpEchoClient> (n0, "10.1.1.2",
- port, 1, Seconds(1.), 1024);
-
- Ptr<UdpEchoServer> server = CreateObject<UdpEchoServer> (n1, port);
-
- server->Start(Seconds(1.));
- client->Start(Seconds(2.));
-
- server->Stop (Seconds(10.));
- client->Stop (Seconds(10.));
-
- AsciiTrace asciitrace ("tutorial.tr");
- asciitrace.TraceAllQueues ();
- asciitrace.TraceAllNetDeviceRx ();
-
- Simulator::Run ();
- Simulator::Destroy ();
-}
-@end verbatim
-
-@section A Star Network
-A point-to-point network is considered a special case of a star network. As
-you might expect, the process of constructing a star network is an extension
-of the very simple process used for a point-to-point link. We have provided
-a file for you in the @code{tutorial} directory called @code{tutorial-star.cc}
-that implements a simple star network as seen below.
-
-@sp 1
-@center @image{figures/star,,,,png}
-
-In order to create a star network, we need to be able to instantiate some
-number (greater than one) of net devices on a node. In the name of simplicity
-of use, the @code{PointToPointTopology} topology helper does not allow one to
-do this. We provided a separate topology helper class, the
-@code{PointToPointIpv4Topology} helper class that provides the slightly finer
-granularity we need to accomplish a star network. In order to use this new
-helper we have to load the definitions by including the appropriate file.
-
-@verbatim
- #include "ns3/point-to-point-ipv4-topology.h"
-@end verbatim
-
-The star that we're going to create has a node in the center (@code{n0}) with
-six nodes surrounding (@code{n1} - @code{n6}). You should be able to easily
-find and understand the code that creates these nodes.
-
-@verbatim
- Ptr<Node> n0 = CreateObject<InternetNode> ();
- Ptr<Node> n1 = CreateObject<InternetNode> ();
- Ptr<Node> n2 = CreateObject<InternetNode> ();
- Ptr<Node> n3 = CreateObject<InternetNode> ();
- Ptr<Node> n4 = CreateObject<InternetNode> ();
- Ptr<Node> n5 = CreateObject<InternetNode> ();
- Ptr<Node> n6 = CreateObject<InternetNode> ();
-@end verbatim
-
-Next, we get into the differences between the @code{PointToPointTopology}
-helper and the @code{PointToPointIpv4Topology} helper. The
-@code{PointToPointIpv4Topology} helper looks and feels a little like the
-@code{CsmaIpv4Topology} helper. Just like you created a CSMA channel
-previously, you need to create a point-to-point channel. The following
-code creates a @code{PointToPointChannel} and calls it @code{link01}. You can
-interpret this name as being the channel (or @emph{link}) from node zero to
-node one.
-
-@verbatim
- Ptr<PointToPointChannel> link01 =
- PointToPointIpv4Topology::CreateChannel (DataRate (38400),
- MilliSeconds (20));
-@end verbatim
-
-You need to provide a data rate for the channel which we set at 38400 bits
-per second. You must also provide a speed-of-light delay which we set at
-20 milliseconds.
-
-Just as you added a net device to the nodes in the CSMA tutorial section, you
-do the same here but with a point-to-point net device. The following code
-illustrates how we do that:
-
-@verbatim
- uint32_t nd01 = PointToPointIpv4Topology::AddNetDevice (n0,
- link01);
-@end verbatim
-
-We call the @code{PointToPointIpv4Topology} helper and ask it to add a net
-device to node zero (@code{n0}) and connect it to the appropriate
-point-to-point link (@code{link01}) which you will recall is the serial link
-from node zero to node one.
-
-If you look at the following code, you will see the same calls are repeated
-to create the remaining five point-to-point channels and connect them
-to net devices on node zero.
-
-The next new code is found after the ``spokes'' of the star have been created.
-It looks like the following:
-
-@verbatim
- uint32_t nd1 = PointToPointIpv4Topology::AddNetDevice (n1, link01);
- uint32_t nd2 = PointToPointIpv4Topology::AddNetDevice (n2, link02);
- uint32_t nd3 = PointToPointIpv4Topology::AddNetDevice (n3, link03);
- uint32_t nd4 = PointToPointIpv4Topology::AddNetDevice (n4, link04);
- uint32_t nd5 = PointToPointIpv4Topology::AddNetDevice (n5, link05);
- uint32_t nd6 = PointToPointIpv4Topology::AddNetDevice (n6, link06);
-@end verbatim
-
-Here we are creating the net devices on the nodes surrounding the center node.
-In the first call, we are adding a net device on node one (@code{n1}) and
-connecting that net device to the channel named @code{link01}. Remember that
-we created the channel @code{link01} as the channel connecting node zero and
-node one. We previously created a net device on node zero and attached that
-device to @code{link01}. Here we are connecting the other side of that link
-to node one. The return value from this call is the net device index of the
-created net device.
-
-The next section of code adds addresses to the net devices we just created.
-The first call adds the IP address 10.1.1.1 to the net device going from
-node zero to node one. Recall that we first created a node named @code{n0}
-and a channel called @code{link01}. We added a net device to @code{n0} and
-remembered the net device index as the @code{uint32_t nd01}. This meant
-the net device @emph{nd} on node @emph{0} that we connected to node @emph{1}.
-We call @code{AddAddress} to add an IP address (10.1.1.1) to the net device
-on node zero identified by the net device index @code{nd01}. We provide a
-net mask suitable for a point to point network. This is typically a /30
-address but we don't force that in this API.
-
-After setting up the address on node zero, we do the same for the node on
-the other end of the ``spoke'' --- in this case node one, with its single
-net device. Note that the network number is the same on both sides of this
-network.
-
-@verbatim
- PointToPointIpv4Topology::AddAddress (n0, nd01, "10.1.1.1",
- ``255.255.255.252'');
-
- PointToPointIpv4Topology::AddAddress (n1, nd1, "10.1.1.2",
- ``255.255.255.252'');
-@end verbatim
-
-The following code repeats this pattern assining similar IP addresses to the
-remaining net devices. Note that there are no @code{Mac48Address} address
-assignments --- they are not required.
-
-The rest of the code you should recognize and understand. We are just going
-to echo one packet across the point-to-point link. You should be now be able
-to build and run this example and to locate and interpret the ASCII trace
-file. This is left as an exercise for you.
-
-The file @code{tutorial-star.cc} is reproduced here for your convenience:
-
-@verbatim
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "ns3/log.h"
-#include "ns3/ptr.h"
-#include "ns3/internet-stack.h"
-#include "ns3/point-to-point-channel.h"
-#include "ns3/mac48-address.h"
-#include "ns3/point-to-point-net-device.h"
-#include "ns3/point-to-point-ipv4-topology.h"
-#include "ns3/udp-echo-client.h"
-#include "ns3/udp-echo-server.h"
-#include "ns3/simulator.h"
-#include "ns3/nstime.h"
-#include "ns3/ascii-trace.h"
-#include "ns3/pcap-trace.h"
-#include "ns3/global-route-manager.h"
-
-NS_LOG_COMPONENT_DEFINE ("StarSimulation");
-
-using namespace ns3;
-
-// Network topology
-//
-// n3 n2
-// | /
-// | /
-// n4 --- n0 --- n1
-// / |
-// / |
-// n5 n6
-
-int
-main (int argc, char *argv[])
-{
- LogComponentEnable ("StarSimulation", LOG_LEVEL_INFO);
-
- NS_LOG_INFO ("Star Topology Simulation");
-
- Ptr<Node> n0 = CreateObject<InternetNode> ();
- Ptr<Node> n1 = CreateObject<InternetNode> ();
- Ptr<Node> n2 = CreateObject<InternetNode> ();
- Ptr<Node> n3 = CreateObject<InternetNode> ();
- Ptr<Node> n4 = CreateObject<InternetNode> ();
- Ptr<Node> n5 = CreateObject<InternetNode> ();
- Ptr<Node> n6 = CreateObject<InternetNode> ();
-
- Ptr<PointToPointChannel> link01 =
- PointToPointIpv4Topology::CreateChannel (DataRate (38400),
- MilliSeconds (20));
-
- uint32_t nd01 = PointToPointIpv4Topology::AddNetDevice (n0,
- link01);
-
- Ptr<PointToPointChannel> link02 =
- PointToPointIpv4Topology::CreateChannel (DataRate (38400),
- MilliSeconds (20));
-
- uint32_t nd02 = PointToPointIpv4Topology::AddNetDevice (n0,
- link02);
-
- Ptr<PointToPointChannel> link03 =
- PointToPointIpv4Topology::CreateChannel (DataRate (38400),
- MilliSeconds (20));
-
- uint32_t nd03 = PointToPointIpv4Topology::AddNetDevice (n0,
- link03);
-
- Ptr<PointToPointChannel> link04 =
- PointToPointIpv4Topology::CreateChannel (DataRate (38400),
- MilliSeconds (20));
-
- uint32_t nd04 = PointToPointIpv4Topology::AddNetDevice (n0,
- link04);
-
- Ptr<PointToPointChannel> link05 =
- PointToPointIpv4Topology::CreateChannel (DataRate (38400),
- MilliSeconds (20));
-
- uint32_t nd05 = PointToPointIpv4Topology::AddNetDevice (n0,
- link05);
-
- Ptr<PointToPointChannel> link06 =
- PointToPointIpv4Topology::CreateChannel (DataRate (38400),
- MilliSeconds (20));
-
- uint32_t nd06 = PointToPointIpv4Topology::AddNetDevice (n0, link06);
-
- uint32_t nd1 = PointToPointIpv4Topology::AddNetDevice (n1, link01);
- uint32_t nd2 = PointToPointIpv4Topology::AddNetDevice (n2, link02);
- uint32_t nd3 = PointToPointIpv4Topology::AddNetDevice (n3, link03);
- uint32_t nd4 = PointToPointIpv4Topology::AddNetDevice (n4, link04);
- uint32_t nd5 = PointToPointIpv4Topology::AddNetDevice (n5, link05);
- uint32_t nd6 = PointToPointIpv4Topology::AddNetDevice (n6, link06);
-
- PointToPointIpv4Topology::AddAddress (n0, nd01, "10.1.1.1",
- "255.255.255.252");
-
- PointToPointIpv4Topology::AddAddress (n1, nd1, "10.1.1.2",
- "255.255.255.252");
-
- PointToPointIpv4Topology::AddAddress (n0, nd02, "10.1.2.1",
- "255.255.255.252");
-
- PointToPointIpv4Topology::AddAddress (n2, nd2, "10.1.2.2",
- "255.255.255.252");
-
- PointToPointIpv4Topology::AddAddress (n0, nd03, "10.1.3.1",
- "255.255.255.252");
-
- PointToPointIpv4Topology::AddAddress (n3, nd3, "10.1.2.2",
- "255.255.255.252");
-
- PointToPointIpv4Topology::AddAddress (n0, nd04, "10.1.4.1",
- "255.255.255.252");
-
- PointToPointIpv4Topology::AddAddress (n4, nd4, "10.1.4.2",
- "255.255.255.252");
-
- PointToPointIpv4Topology::AddAddress (n0, nd05, "10.1.5.1",
- "255.255.255.252");
-
- PointToPointIpv4Topology::AddAddress (n5, nd5, "10.1.5.2",
- "255.255.255.252");
-
- PointToPointIpv4Topology::AddAddress (n0, nd06, "10.1.6.1",
- "255.255.255.252");
-
- PointToPointIpv4Topology::AddAddress (n6, nd6, "10.1.6.2",
- "255.255.255.252");
-
- uint16_t port = 7;
-
- Ptr<UdpEchoClient> client = CreateObject<UdpEchoClient> (n0, "10.1.1.2",
- port, 1, Seconds(1.), 1024);
-
- Ptr<UdpEchoServer> server = CreateObject<UdpEchoServer> (n1, port);
-
- server->Start(Seconds(1.));
- client->Start(Seconds(2.));
-
- server->Stop (Seconds(10.));
- client->Stop (Seconds(10.));
-
- AsciiTrace asciitrace ("tutorial.tr");
- asciitrace.TraceAllQueues ();
- asciitrace.TraceAllNetDeviceRx ();
-
- Simulator::Run ();
- Simulator::Destroy ();
-}
-@end verbatim
-
-@subsection Routing
-If you are really excited about this simulator you may have already tried to
-modify the scripts outside the tutorial. I know that one of the first things
-that would have occurred to me when I saw the star network would have been to
-start trying to add applications to echo packets from nodes other than zero.
-If you tried, for example, to start the echo client on node one instead of
-node zero, you would have found an empty trace file. The reason for this
-is that you have now created an internetwork. This means you will need to
-enable internetwork routing.
-
-We have provided a file for you in the @code{tutorial} directory called
-@code{tutorial-star-routing.cc} to show you how this is done. This extremely
-tricky and difficult change is shown below:
-
-@verbatim
- GlobalRouteManager::PopulateRoutingTables ();
-@end verbatim
-
-This one-line addition, located just before the simulation runs, tells the
-@command{ns-3} @emph{global route manager} to walk the topology you created and
-build internetwork routing tables for all of the nodes in the simulation.
-We changed the client application so that it runs on node four:
-
-@verbatim
- Ptr<UdpEchoClient> client = CreateObject<UdpEchoClient> (n4, "10.1.1.2",
- port, 1, Seconds(1.), 1024);
-@end verbatim
-
-Now if you build and run @code{tutorial-star-routing.cc} you can examine the
-@code{tutorial.tr} file and see that your UDP echo packets are now correctly
-routed through the topology.
-
-@section A Dumbbell Network
-One of the most interesting simple topologies (from a phenomenological point of
-view) is commonly called a dumbbell network. The name derives from a
-superficial similarity in form to a piece of exercise equipment.
-
-The dumbbell model is typically composed of two bus or star network elements
-connected via a point-to-point link. The point-to-point link is usually
-configured with a lower bandwidth than the bus elements to provide a
-@emph{choke point}.
-
-The following is a representation of the topology.
-
-@sp 1
-@center @image{figures/dumbbell,,,,png}
-
-We have provided a file that constructs this dumbbell network and creates
-enough data flowing across the choke point that some packets will be dropped.
-The file is called @code{tutorial-linear-dumbbell.cc} and is located in the
-@code{tutorial} directory. We have already covered all of the code used to
-create this network, so we will just quickly go over the main sections of the
-script.
-
-The first section creates a CSMA lan that will become the left side of the
-dumbbell network. This code should be very familiar since we used the same
-process to create our first example.
-
-@verbatim
-//
-// Create the lan on the left side of the dumbbell.
-//
- Ptr<Node> n0 = CreateObject<InternetNode> ();
- Ptr<Node> n1 = CreateObject<InternetNode> ();
- Ptr<Node> n2 = CreateObject<InternetNode> ();
- Ptr<Node> n3 = CreateObject<InternetNode> ();
-
- Ptr<CsmaChannel> lan1 =
- CsmaTopology::CreateCsmaChannel (DataRate (10000000), MilliSeconds (2));
-
- uint32_t nd0 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n0, lan1,
- "08:00:2e:00:00:00");
-
- uint32_t nd1 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n1, lan1,
- "08:00:2e:00:00:01");
-
- uint32_t nd2 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n2, lan1,
- "08:00:2e:00:00:02");
-
- uint32_t nd3 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n3, lan1,
- "08:00:2e:00:00:03");
-
- CsmaIpv4Topology::AddIpv4Address (n0, nd0, "10.1.1.1", "255.255.255.0");
- CsmaIpv4Topology::AddIpv4Address (n1, nd1, "10.1.1.2", "255.255.255.0");
- CsmaIpv4Topology::AddIpv4Address (n2, nd2, "10.1.1.3", "255.255.255.0");
- CsmaIpv4Topology::AddIpv4Address (n3, nd3, "10.1.1.4", "255.255.255.0");
-@end verbatim
-
-The code to generate the CSMA lan on the right side is similar; only the names
-have been changed.
-
-@verbatim
-//
-// Create the lan on the right side of the dumbbell.
-//
- Ptr<Node> n4 = CreateObject<InternetNode> ();
- Ptr<Node> n5 = CreateObject<InternetNode> ();
- Ptr<Node> n6 = CreateObject<InternetNode> ();
- Ptr<Node> n7 = CreateObject<InternetNode> ();
-
- Ptr<CsmaChannel> lan2 =
- CsmaTopology::CreateCsmaChannel (DataRate (10000000), MilliSeconds (2));
-
- uint32_t nd4 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n4, lan2,
- "08:00:2e:00:00:04");
-
- uint32_t nd5 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n5, lan2,
- "08:00:2e:00:00:05");
-
- uint32_t nd6 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n6, lan2,
- "08:00:2e:00:00:06");
-
- uint32_t nd7 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n7, lan2,
- "08:00:2e:00:00:07");
-
- CsmaIpv4Topology::AddIpv4Address (n4, nd4, "10.1.2.1", "255.255.255.0");
- CsmaIpv4Topology::AddIpv4Address (n5, nd5, "10.1.2.2", "255.255.255.0");
- CsmaIpv4Topology::AddIpv4Address (n6, nd6, "10.1.2.3", "255.255.255.0");
- CsmaIpv4Topology::AddIpv4Address (n7, nd7, "10.1.2.4", "255.255.255.0");
-@end verbatim
-
-Next, we create a point to point link to connect the two lans. We connect
-the point-to-point channel between nodes three (on the left lan) and four
-(on the right lan). You should recoginze this as substantially similar to
-the link setup from the @code{point-to-point} example.
-
-@verbatim
-//
-// Create the point-to-point link to connect the two lans.
-//
- Ptr<PointToPointChannel> link = PointToPointTopology::AddPointToPointLink (
- n3, n4, DataRate (38400), MilliSeconds (20));
-
- PointToPointTopology::AddIpv4Addresses (link, n3, "10.1.3.1",
- n4, "10.1.3.2");
-@end verbatim
-
-Then we configure data flows. We create four echo clients that send UDP
-packets from the left side lan to servers created on the right side lan.
-Notice that we send 100 packets with an inter-packet gap of ten milliseconds
-instead of the single packet we have previously used. This data rate is
-sufficient to saturate the point-to-point link and will cause packets to be
-dropped when the queue on the link net devices overflows (the default maximum
-queue depth is 100 packets). Note that we stagger the start of the echo
-clients to slowly bring up the data rates.
-
-@verbatim
-//
-// Create data flows across the link:
-// n0 ==> n4 ==> n0
-// n1 ==> n5 ==> n1
-// n2 ==> n6 ==> n2
-// n3 ==> n7 ==> n3
-//
- uint16_t port = 7;
-
- Ptr<UdpEchoClient> client0 = CreateObject<UdpEchoClient> (n0, "10.1.2.1",
- port, 100, Seconds(.01), 1024);
- Ptr<UdpEchoClient> client1 = CreateObject<UdpEchoClient> (n1, "10.1.2.2",
- port, 100, Seconds(.01), 1024);
- Ptr<UdpEchoClient> client2 = CreateObject<UdpEchoClient> (n2, "10.1.2.3",
- port, 100, Seconds(.01), 1024);
- Ptr<UdpEchoClient> client3 = CreateObject<UdpEchoClient> (n3, "10.1.2.4",
- port, 100, Seconds(.01), 1024);
-
- Ptr<UdpEchoServer> server4 = CreateObject<UdpEchoServer> (n4, port);
- Ptr<UdpEchoServer> server5 = CreateObject<UdpEchoServer> (n5, port);
- Ptr<UdpEchoServer> server6 = CreateObject<UdpEchoServer> (n6, port);
- Ptr<UdpEchoServer> server7 = CreateObject<UdpEchoServer> (n7, port);
-
- server4->Start(Seconds(1.));
- server5->Start(Seconds(1.));
- server6->Start(Seconds(1.));
- server7->Start(Seconds(1.));
-
- client0->Start(Seconds(2.));
- client1->Start(Seconds(2.1));
- client2->Start(Seconds(2.2));
- client3->Start(Seconds(2.3));
-
- server4->Stop (Seconds(10.));
- server5->Stop (Seconds(10.));
- server6->Stop (Seconds(10.));
- server7->Stop (Seconds(10.));
-
- client0->Stop (Seconds(10.));
- client1->Stop (Seconds(10.));
- client2->Stop (Seconds(10.));
- client3->Stop (Seconds(10.));
-@end verbatim
-
-The remainder of the file should be quite familiar to you. Go ahead and
-run @code{tutorial-linear-dumbbell}. Now take a look at the trace
-(@code{tutorial.tr}) file. You will now see trace lines that begin with
-@code{d}. Alternatively you can search for the string ``queue-drop'' which
-is the expansion of the drop code ('d').
-
-Interpretation of a dropped packet is straightforward. We have expanded
-the first @code{queue-drop} trace for you below. See the section on ASCII
-tracing for details.
-
-@verbatim
- 00 d
- 01 2.40938
- 02 nodeid=3
- 03 device=1
- 04 queue-drop
- 05 pkt-uid=124
- 06 LLCSNAP(type 0x800)
- 07 IPV4(
- 08 tos 0x0
- 09 ttl 63
- 10 id 20
- 11 offset 0
- 12 flags [none]
- 13 length: 1052) 10.1.1.3 > 10.1.2.3
- 14 UDP(length: 1032)
- 15 49153 > 7
- 16 DATA (length 1024)
-@end verbatim
-
-We leave it as an exercise to examine the trace files in more detail.
-
-@c ========================================================================
-@c Nonlinear Thinking
-@c ========================================================================
-
-@node Nonlinear-Thinking
-@chapter Nonlinear Thinking
-
-One thing that all of our examples so far have in common is that they are
-composed of a linear collection of calls into the @command{ns-3} system. The
-programmers among the readers may have wondered why there is not as much
-as a for-loop in all of the examples. The answer is that we wanted to
-introduce you to @command{ns-3} scripting with a minimum of conceptual
-overhead. We're going to remedy that situation shortly.
-
-We have written a number of @command{ns-3} scripts in C++. Although we have
-been perfectly linear in our script implementations, just like any other C++
-program, an @command{ns-3} script can use any features of the language you
-desire. If you will look back at the @code{tutorial-linear-dumbbell.cc}
-example, you may notice that the code to create the left and right sides of
-the dumbbell is operationally identical --- only the names change. An obvious
-improvement of this program would be to use subroutines to create the sides.
-Since we are working with C++, we should probably do this in an
-object-oriented way. Since object-oriented design is somewhat of a black art
-to some people, we'll take some time here and outline a simple methodology
-you can follow.
-
-@section Object Design 101 --- Class Ipv4BusNetwork
-If you are a master of object oriented design, feel free to skip or skim this
-section, in which we derive a simplistic but fully operational bus network
-class.
-
-So you want to create a BusNetwork class. Often the biggest hurdle in a
-design is figuring out how to get started. One of the simplest and most
-straightforward ways to do an object decomposition of a problem is to simply
-write down a description of the problem and take a look at the words
-you used. Let's take some time and do that, first at a very high level.
-
-@example
-A bus network is an implementation of a particular network topology that
-contains some number of nodes. Each of these nodes is attached to a single
-multi-drop channel. The network itself has some attributes independent of
-the topology such as a network mask, network number (prefix) and base IP
-address.
-@end example
-
-The first thing to do is to focus on the nouns and adjectives. These will
-give you a starting point for required classes and member variables.
-
-Immediately we can notice that at the highest level we are talking about the
-noun @emph{network}. This probably won't surprise you. We also have an
-adjective that modifies the noun --- @emph{bus}. This should lead us to our
-first class defintion. Usually class names are constructed in the same way
-as an English language sentence would be spoken. For example, one would speak
-of a @emph{bus network} in conversation, so we would normally create a
-@code{class BusNetwork} to represent it.
-
-One thing to note is that we have used two words in our description quite
-naturally: @emph{is} and @emph{has}. When you see these words should should
-immediately think of the object-oriented concepts of @emph{ISA} (inheritance)
-and @emph{HASA} (containment) respectively. We wrote that a bus network
-@emph{is} an implementation of a particular network topology. Perhaps you
-will agree that there is a natural base class called @code{Network} that
-@emph{has} the attributes discussed above. The fact that a @code{BusNetwork}
-@emph{ISA} kind of @code{Network} suggests inheritance. Let's capture that
-thought right away remembering that we're focused on IP version four here:
-
-@verbatim
- class Ipv4Network
- {
- public:
- Ipv4Address m_network;
- Ipv4Mask m_mask;
- Ipv4Address m_baseAddress;
- };
-
- class Ipv4BusNetwork : public Ipv4Network
- {
- };
-@end verbatim
-
-Let's take a look at the @emph{HASA} relationships of the bus network. Clearly
-it will @emph{have} a reference to the underlying channel that implements the
-actual communications medium. We use smart pointers for those references, so
-one member variable is obvious:
-
-@verbatim
- Ptr<CsmaChannel> m_channel;
-@end verbatim
-
-A bus network will also need to contain references to all of the nodes we
-eventually want to create. If you are working in C++ and see the words contain
-or container, you should immediately think of the Standard Template Library
-or STL. A quick search of the available containers there will probably lead
-you to consider the vector class. A vector is a container that looks like an
-array. This is just what we need here. Again, we want to use smart pointers
-to reference our nodes, so the declaration of the vector would look like,
-
-@verbatim
- std::vector<Ptr<Node> > m_nodes;
-@end verbatim
-
-It will save you headaches in the future if you notice that the space between
-the two right brackets is required to differentiate this situation from a
-right-shift operator. So we have a pretty good start already after just a
-little work. Now we need to turn our attention to actions. Let's write
-another little description of the things you consider doing to a Bus network.
-
-@example
-We need to be able to create a bus network. We need to be able to delete a
-bus network. We need to be able to get a handle to a node in order to add
-applications. We need to be able to set the network, mask and base address
-somehow, specify how many nodes to create and provide the underlying channel
-its required bandwidth and delay parameters.
-@end example
-
-We now look at the @emph{verbs} in that sentence. These will give a good
-starting point for the methods of the classes. For example, the verbs
-@emph{create} and @emph{delete} should suggest @emph{constructor} and
-@emph{destructor}. The verb @emph{get} leads us to providing a method called
-@code{GetNode}. We have to provide a number of parameters so we can either
-provide @emph{setters} or we can simply pass them in as parameters to our
-constructors. Since this is a simple example, we won't bother to implement
-getters and setters (methods to get and set member variables to enhance data
-hiding). Let's use this guidance to finish up our class declarations:
-
-@verbatim
- class Ipv4Network
- {
- public:
- Ipv4Network (Ipv4Address network, Ipv4Mask mask, Ipv4Address address);
- virtual ~Ipv4Network ();
-
- Ipv4Address m_network;
- Ipv4Mask m_mask;
- Ipv4Address m_baseAddress;
- };
-
- class Ipv4BusNetwork : public Ipv4Network
- {
- public:
- Ipv4BusNetwork (
- Ipv4Address network,
- Ipv4Mask mask,
- Ipv4Address startAddress,
- DataRate bps,
- Time delay,
- uint32_t n);
-
- virtual ~Ipv4BusNetwork ();
-
- Ptr<Node> GetNode (uint32_t n);
-
- private:
- std::vector<Ptr<Node> > m_nodes;
- Ptr<CsmaChannel> m_channel;
- };
-@end verbatim
-
-That's it. We have actually already walked through almost all of the code
-required to construct a bus network in our @code{tutorial-csma-echo.cc}
-example, so let's just jump forward and take a look at an implementation
-of this thing. We provide an implementation for you in the files
-@code{ipv4-bus-network.h} and @code{ipv4-bus-network.cc} located in the
-@code{tutorial} directory. We also provide an example that uses the new
-class in the file @code{tutorial-bus-network.cc}.
-
-The interesting method from our current perspective is the Ipv4BusNetwork
-constructor, shown below:
-
-@verbatim
- Ipv4BusNetwork::Ipv4BusNetwork (
- Ipv4Address network,
- Ipv4Mask mask,
- Ipv4Address baseAddress,
- DataRate bps,
- Time delay,
- uint32_t n)
- :
- Ipv4Network (network, mask, baseAddress)
- {
- Ipv4AddressGenerator::SeedNetwork (mask, network);
- Ipv4AddressGenerator::SeedAddress (mask, baseAddress);
-
- m_channel = CsmaTopology::CreateCsmaChannel (bps, delay);
-
- for (uint32_t i = 0; i < n; ++i)
- {
- Ptr<Node> node = CreateObject<InternetNode> ();
- uint32_t nd = CsmaIpv4Topology::AddIpv4CsmaNetDevice (node, m_channel,
- Mac48Address::Allocate ());
- Ipv4Address address = Ipv4AddressGenerator::AllocateAddress (mask,
- network);
- CsmaIpv4Topology::AddIpv4Address (node, nd, address, mask);
- m_nodes.push_back (node);
- }
- }
-@end verbatim
-
-Notice that we do the simple and straightforward thing and pass all of our
-parameters to the constructor. For those unfamiliar with C++, the line after
-the colon and before the opening brace (shown below),
-
-@verbatim
- :
- Ipv4Network (network, mask, baseAddress)
- {
-@end verbatim
-
-Passes the appropriate parameters to the constructor of the base class
-@code{Ipv4Network}. There are two new calls that we haven't seen immediately
-after this initialization. They are:
-
-@verbatim
- Ipv4AddressGenerator::SeedNetwork (mask, network);
- Ipv4AddressGenerator::SeedAddress (mask, baseAddress);
-@end verbatim
-
-We provide an IP address generator class to allow us to programatically
-allocate IP addresses. The first call to @code{SeedNetwork} gives the
-address generator a starting network number to use when generating addresses.
-The second call to @code{SeedAddress} gives the address generator a starting
-IP address to use. There is a starting network and starting address for each
-of the 32 possible network masks. Later in the for loop, you will see a
-call to @code{AllocateAddress} in which the IP address for each node created
-in the loop is actually generated.
-
-The only unfamiliar call in the reset of the constructor will be:
-
-@verbatim
- m_nodes.push_back (node);
-@end verbatim
-
-This is the STL code to add the newly created node to the vector of nodes
-attached to the bus.
-
-For your convenience, we reproduce the entire bus network implementation below:
-
-@verbatim
- /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
- /*
- * Copyright (c) 2007 University of Washington
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
- #include "ns3/mac48-address.h"
- #include "ns3/csma-net-device.h"
- #include "ns3/csma-topology.h"
- #include "ns3/csma-ipv4-topology.h"
-
- #include "ipv4-bus-network.h"
- #include "ipv4-address-generator.h"
-
- namespace ns3 {
-
- Ipv4Network::Ipv4Network (
- Ipv4Address network,
- Ipv4Mask mask,
- Ipv4Address address)
- :
- m_network (network), m_mask (mask), m_baseAddress (address)
- {
- }
-
- Ipv4Network::~Ipv4Network ()
- {
- }
-
- Ipv4BusNetwork::Ipv4BusNetwork (
- Ipv4Address network,
- Ipv4Mask mask,
- Ipv4Address baseAddress,
- DataRate bps,
- Time delay,
- uint32_t n)
- :
- Ipv4Network (network, mask, baseAddress)
- {
- Ipv4AddressGenerator::SeedNetwork (mask, network);
- Ipv4AddressGenerator::SeedAddress (mask, baseAddress);
-
- m_channel = CsmaTopology::CreateCsmaChannel (bps, delay);
-
- for (uint32_t i = 0; i < n; ++i)
- {
- Ptr<Node> node = CreateObject<InternetNode> ();
- uint32_t nd = CsmaIpv4Topology::AddIpv4CsmaNetDevice (node, m_channel,
- Mac48Address::Allocate ());
- Ipv4Address address = Ipv4AddressGenerator::AllocateAddress (mask,
- network);
- CsmaIpv4Topology::AddIpv4Address (node, nd, address, mask);
- m_nodes.push_back (node);
- }
- }
-
- Ipv4BusNetwork::~Ipv4BusNetwork ()
- {
- }
-
- Ptr<Node>
- Ipv4BusNetwork::GetNode (uint32_t n)
- {
- return m_nodes[n];
- }
-
- }; // namespace ns3
-@end verbatim
-
-@section Using Ipv4BusNetwork
-If all you ever want to do with a bus network can be captured in a topology
-with four nodes on the bus, the preceeding section may seem like a colossal
-waste of time. This is probably not the case, though. Now that we have a
-relatively abstract bus class, we can create bus networks with 4, 40 or 4000
-nodes with no additional effort.
-
-A use of the bus network class is shown in the file
-@code{bus-netowrk.cc} located in the @code{tutorial} directory. The
-interesting code is,
-
-@verbatim
- Ipv4BusNetwork bus ("10.1.0.0", "255.255.0.0", "0.0.0.3",
- DataRate(10000000), MilliSeconds(20), 10);
-@end verbatim
-
-Here we create a bus network with the network number ``10.1.0.0'' and the
-network mask ``255.255.0.0'' that completes the IP network definition. You
-can consider these together as ``10.1.0.0/16'' if you prefer. The next
-parameter tells the bus to start numbering IP addresses of contained nodes at
-``10.1.0.3'' (remember the network number will be combined). We provided a
-data rate of 10 megabits per second and a latency of 20 milliseconds.
-Finally, we ask the @code{Ipv4BusNetwork} object to create ten nodes in the
-network.
-
-If you are feeling brave, go ahead and change the number of nodes to be 100,
-1000, 10,000 or more to generate larger and larger networks. Before you go
-too far, remember that a trace file will be generated when you run your
-resulting program and ee asked the trace facility to trace all net device
-receive events. This will include the reception of the broadcast ARP request
-by all of the nodes in the simulation, so this can add up quickly.
-
-@c ========================================================================
-@c Summary
-@c ========================================================================
-
-@node Summary
-@chapter Summary
-
-This concludes the first part of the tutorial. We have focused on
-using the @command{ns-3} system to construct various network topologies and to
-simulate sendng data across the networks; and we've shown you how to use the
-trace facility to get access to simulation results.
-
-We now encourage you to play with the system a little. Experiment with what
-we have provided. Build a hierarchical network simulation. Perhaps exercise
-your object design skills and create a new @code{Ipv4DumbbellNetwork} class
-to create dumbbell networks using the Ipv4BusNetwork class we just created.
-Hint: An Ipv4DumbbellNetwork @emph{has} two @code{Ipv4BusNetwork} objects;
-a left side and a right side.
-
-In the next part of the tutorial we are going to drop down a level and begin
-examining the lower levels of the system in more detail. We are going to
-explain how to change the behavior of the system and eventually how to write
-new models and applications. This is a good time to make sure that you
-thorougly understand what we've gone over so far.
-
-@c ========================================================================
-@c Object Model
-@c ========================================================================
-
-@node Object-Model
-@chapter Object Model
-
-@cindex Object Model
-There are two distinctly different meanings associated with the term Object
-Model. The first speaks to the implementation of an object system --- a system
-view; and the second speaks to the application programming interface (classes
-or objects) one uses to access some service or system --- an application view.
-
-As an example of the system view sense of the term, the C++ language has an
-associated object model that describes how objects are laid out in memory,
-how virtual functions work, how inheritance is implemented, constructor and
-destructor execution ordering, template instantiation, etc.
-
-@cindex API
-@cindex DOM
-@cindex Document Object Model
-In the case of the application view, the Document Object Model is a good
-example. In the words of W3C, the Document Object Model (DOM) is an
-application programming interface (API) for HTML and XML documents. It defines
-the logical structure of documents and the way a document is accessed and
-manipulated.
-
-@cindex API
-@cindex COM
-@cindex Component Object Model
-The Component Object Model (COM) from Microsoft actually spans both meanings
-of the term and extends further into policy statements. From a system
-perspective, COM specifies an interface definition language, the layout of
-objects virtual function tables, the formats of Globally Unique Identifiers
-and also specifies lifetime management mechanisms for objects via reference
-counting. From the point of view of the API, COM specifies a number of
-Interfaces as well as functions such as CoCreateInstance and various
-threading models. The COM specification extends to policy by disallowing
-implementation inheritance.
-
-@cindex Feynman
-The @command{ns-3} object model takes the C++ language (system level) object
-model as its basis, and extends that model by providing an API for software
-componentry. You may find terms like Component, Interface and QueryInterface
-in the following discussion, or used informally in other discussions about
-@command{ns-3}. It is important to understand from the outset that this is
-the @command{ns-3} object model, and not any other object model.
-Richard Feynman (an American physicist) once described the behavior of matter
-and light on a very small scale in the following way,
-
-@quotation
-``They do not behave like waves, they do not behave like particles, they do
-not behave like clouds, or billiard balls, or weights on springs, or like
-anything that you have ever seen.''
-@end quotation
-
-Just as students of quantum mechanics must rid themselves of preconceptions
-regarding the behavior of matter at small scales, you should rid yourself of
-any preconceptions you may have about components, interfaces and APIs for
-software componentry before continuing. To paraphrase Feynman, @command{ns-3}
-components do not behave like COM Components, or Java Beans, or CORBA
-objects, or clouds or weights on springs, or like anything that you have
-ever seen --- they are @command{ns-3} components.
-
-@section The C++ Object Model is the Root of all Things
-@command{Ns-3} is primarily a C++ system. The system is written in C++ and
-one can use standard C++ mechanisms for creating and using ns-3 objects. We
-do not change this at all, nor do we make any pronouncements about the
-superiority of one mechanism or another. What we will do is provide
-convenience functions that we think will make creating and managing simulation
-objects easier.
-
-@cindex CreateObject
-Previously, you have seen objects created using the template function
-@code{CreateObject} as in the following example:
-
-@verbatim
- Ptr<Node> n0 = CreateObject<InternetNode> ();
-@end verbatim
-
-This line of code, while it may be unfamiliar to some, is pure C++. If you
-were to look in the header file ptr.h, you would find the following definition
-of the @code{CreateObject} template.
-
-@verbatim
- template <typename T>
- Ptr<T> CreateObject (void)
- {
- Ptr<T> p = Ptr<T> (new T (), false);
- p->SetTypeId (T::GetTypeId ());
- return p;
- }
-@end verbatim
-
-@cindex template
-As you can see, this template creates objects of type @code{T} using the
-operator @code{new}. Its a little harder to find the corresponding delete ---
-it's in the file @code{object.cc} inside the method @code{Object::MaybeDelete},
-but when that @code{Ptr} which you see above goes out of scope it will call
-@code{Unref} and ultimately the C++ @code{delete} operator will be called.
-
-@cindex new
-@cindex delete
-The ns-3 system uses the C++ @code{new} and @code{delete} operators, so there
-is really no reason that you as a user of the ns-3 system are forbidden from
-using these or any other C++ mechanism. If you so desire, you can take on
-the responsibility for managing object lifetime (i.e., do not use the
-@code{Ptr} smart pointer), work directly with the @code{new} and @code{delete}
-operators and call methods like any C++ object as in the following example:
-
-@verbatim
- MyClass *obj = new MyClass ();
- obj->Method();
- delete obj;
-@end verbatim
-
-@cindex model
-You, as a competent model author, are encouraged to use whatever methods you
-think are appropriate in your private code. Remember, however, that the
-public ns-3 APIs do use smart pointers to pass objects around in an effort to
-reduce the burden of object lifetime management. If you do intend to export
-an API publicly, you should use the same object lifetime management approaches
-as those found in the ns-3 public API if only for consistency.
-
-These APIs are there for convenience and consistency, but do not change the
-fact that in ns-3 all of the objects are really just C++ objects, ultimately
-created using the C++ new operator with C++ constructor semantics and are
-ultimately deleted using the C++ delete operator, following C++ destructor
-semantics. Although it may sometimes appear so, there is really no system-
-level magic going on in ns-3. Ns-3 components and interfaces are C++ objects
-just like any other object and our object model is simply a collection of APIs
-built on the normal C++ object model.
-
-@cindex Interface
-@cindex Abstract Data Type
-@cindex ADT
-@cindex Abstract Base Class
-@cindex ABC
-@section Interface
-There are many different ideas floating around of what exactly the term
-@emph{interface} means. Originally an interface just meant a communication
-boundary between two entities. As the concepts of object oriented programming
-(OOP) were surfacing in the 1980s, the term interface was applied to the
-collection of access methods for the modular entities that were being defined.
-
-@cindex OOP
-@cindex Object Oriented Programming
-Two distinct approaches developed regarding specifying access mechanisms for
-objects. The OOP purists were very concerned about object reuse and were led
-to Abstract Data Types (ADT). These were eventually implemented in the case
-of C++, as pure virtual methods in Abstract Base Classes (ABC). Another group
-of folks was more interested in simply specifying object access methods in one
-place and using inheritance as the primary reuse mechanism.
-
-Bjarne Stroustroup, the creator of C++, embraced both approaches. He makes
-the following interesting observation:
-
-@quotation
-``Many classes [@dots{}] are useful both as themselves and also as bases for
-derived classes. [@dots{}] Some classes, such as class @strong{Shape},
-represent abstract concepts for which objects cannot exist.''
-@end quotation
-
-@cindex PIMPL
-@command{Ns-3} does not pick and enforce a particular approach. In
-@command{ns-3} an interface is determined completely by a class declaration
-just as any C++ object interface is declared. If you think of an object as
-an abstract concept that should be implemented by derived classes, by all
-means, use the Abstract Base Class approach to interface declaration. If you
-think that an object should be completely concrete and you foresee no need
-to ever modify its behavior, feel free to avoid declaring any methods virtual.
-If you think that an object could be useful as a base class, feel free to
-declare its methods virtual. If you like to use the PIMPL idiom, again, feel
-free. If you want to use any combination of these techniques, feel free.
-We make no restrictions.
-
-@cindex API
-When we speak of an ns-3 interface, we do not worry about interface definition
-languages, or pure virtual classes, or registries we just think about C++
-object declarations and their associated methods. We tend to think of
-interfaces to objects as simply a private or public API. When we instantiate
-an @command{ns-3} interface, it is the C++ object model that dictates how that
-object is brought into existence. When a method is called on an @command{ns-3}
-Interface, it is the C++ object model that dictates how that method is
-dispatched.
-
-We do, however, provide a base class that endows vanilla C++ objects with
-capabilities that can be seen as conceptually similar to those provided by
-Microsoft Component Model @emph{Interfaces}.
-
-@section The Ns-3 Object and GetObject
-@cindex Component Object Model
-One thing that Microsoft arguably got right in the Component Object Model was
-the idea of Interface aggregation and discovery via QueryInterface. We have
-embraced these ideas in @command{ns-3}. This was done primarily to address a
-common problem in large software systems. A good example of this problem
-happens in the @command{ns-3} Node class.
-
-@cindex OOP
-@cindex weak base class
-@cindex base class bloat
-@cindex Swiss Army Knife class
-@cindex Node
-If one were to take the standard OOP view of specializing a @code{Node} into
-an internet host, for example, one would typically inherit from the @code{Node}
-base class and include functionality to implement such things as internet
-routing and a TCP/IP protocol stack. Other types of @code{Node}s might
-inherit from the node class and specialize in different ways, or further
-specialize the internet host class, treating it as a base class. This can
-result in a complicated inheritance tree in which some specializations are
-simply not available to other branches of the tree which can make reuse
-difficult or impossible. This is known as the @emph{weak base class} problem
-and creates pressure to drive functionality up the inheritance tree into the
-base classes. This, in turn, results in @emph{base class bloat} and the
-resulting @emph{swiss army knife} base classes which end up trying to do
-everything in one place.
-
-Even if one successfully avoided these swiss army knife base classes, one
-would also want to be able to treat new specializations of @code{Node}
-generically in the system. This means one would pass references to the base
-class (@code{Node}) across public APIs. This introduces @emph{upcasts} prior
-to passing across public APIs and corresponding @emph{downcasts} on the other
-side in order to gain access to required specialized functions. As the
-inheritance tree becomes more complicated, this approach can cause another
-related problem known as the @emph{fragile base class} problem. This happens
-when changes to the base class cause unexpected problems in the various and
-sundry subclasses.
-
-These effects seem always to result in a positive feedback loop driving
-everything into the base class and destroying much of the encapsulation which
-is a hallmark of the object oriented approach.
-
-@subsection Interface Composition
-@cindex Node
-There is a completely different way to address the Node specialization
-problem. Instead of approaching the situation using inheritance, one can
-look at the problem as one of composition. We can look at the @code{Node}
-class as a container of sorts that holds other objects. In this case, the
-objects would be instances of the classes implementing the internetwork
-routing code, or the TCP/IP protocol stack described above. This approach
-preserves the encapsulation and solves the weak base class, base class bloat
-and fragile base class problems; but the question of method dispatch
-immediately comes to mind.
-
-@cindex delegation
-In many systems, @emph{delegation} is used. The base class, @code{Node},
-in this approach would provide methods that simply forward to the objects
-implementing the desired functionality. This situation clearly does not
-address the base class bloat problem since dispatch methods must be added
-to the base class. The situation is mitigated somewhat by pushing the
-implementation of the dispatch methods to contained objects, but the
-fundamental problems are still present. What is really needed is a way
-to compose objects but at the same time keep the interfaces to those
-objects separated.
-
-@cindex aggregation
-Composition, usually called @emph{aggregation}, along with runtime Interface
-discovery is the solution that Microsoft originally championed and that
-@command{ns-3} has adopted --- albeit with many simplifications and a few name
-changes.
-
-@subsection Objects and Interfaces
-@cindex COM
-@cindex QueryInterface
-Now that we have mentioned Microsoft COM and are almost obligated to mention
-the terms Interface and QueryInterface. For those familiar with COM, loosely
-speaking, QueryInterface is to COM as GetObject is to @command{ns-3}.
-The analogy, while good conceptually, is superficial from an implementation
-point of view.
-
-@cindex Node
-Addressing our current example of a @code{Node}, generically speaking, each
-node needs to aggregate an object that will implement internetwork routing
-and TCP/IP. The system will need to provide a mechanism for locating the
-aggregated objects and allow a client to discover them.
-
-@cindex aggregation
-@cindex Object
-These aggregated objects have interfaces in the C++ sense of collections of
-method signatures. In @command{ns-3}, when objects are capable of
-participating in this aggregation process, they are called @command{ns-3}
-@code{Objects}. @code{Objects} receive the functionality required for this
- participation by inheriting from the @command{ns-3} base class @code{Object}.
-
-Note well that when we write the word @code{Object} (note the uppercase 'O' in
-the spelling and the change of font) we are referring to a kind of C++ object
-that has inherited the capability of participating in an aggregation. The
-@command{ns-3}-specific word @code{Object} can have a significantly different
-meaning than that of a vanilla C++ object outside the aforementioned
-inheritance tree, and the difference is only readily apparent via context.
-In this tutorial we will always write the @command{ns-3}-specific kind of
-@code{Object} in a fixed font; and will write the vanilla C++ term object in
-normal font. In conversation, you will need to be careful to understand which
-term is meant: object or @code{Object}.
-
-Once an object has inherited from class @code{Object} it has the ability to
-@emph{host} an aggregation. This means that it has the ability to add other
-@code{Objects} to its aggregation via the method @code{AggregateObject}. It
-also means that it can provide a service to @emph{discover} other objects in
-its aggregation via the method @code{GetObject}.
-
-@cindex base class
-Technically, the class named @code{Object} is simply a base class that you
-will inherit from if you want your @code{Objects} to support aggregation and
-discovery. Many systems have a base class that implements common
-functionality and these base classes are typically called somthing like
-Object. The @command{ns-3} version of this base class relates primarily to
-@code{Object} aggregation and discovery, although it does also provide methods
-to help with intrusive reference counting and tracing as well.
-
-When a C++ object inherits from the ns-3 Object base class, it is conceptually
-promoted to an ns-3 @code{Object} irrespective of how the object was declared
-(e.g., as an abstract base class, concrete class, with virtual methods, etc.).
-In ns-3, you should associate inheritance from the class named @code{Object}
-with promotion of an object to the status of some locatable @code{Object}
-rather than with the form of the class declaration.
-
-@cindex COM
-@cindex CORBA
-@cindex ORBit
-For those of you unfamiliar with Microsoft COM, CORBA or ORBit, this might
-sound obvious. For those of with such a background, the point we are making
-is that there is no such thing in @command{ns-3} as a separate Interface
-declaration, no such thing as an Interface Definiition Language, no such thing
-as a UUID or GUID, etc. In @command{ns-3} we just work with C++ objects that
-may be given some very useful abilities by inheriting from the @command{ns-3}
-base class @code{Object}. @command{Ns-3} @code{Objects} are not required to
-inherit from classes composed of pure virtual methods in order to define an
-Interface. It's all really just ``plain old C++.''
-
-To summarize, when you instantiate an object that inherits from the
-@code{Object} class, you will have a C++ object that has four important
-properties:
-
-@cindex AggregateObject
-@cindex GetObject
-@itemize @bullet
-@item The @code{Object} has a C++ interface defined by the collection of method signatures in its inheritance tree;
-@item The @code{Object} has some way to identify its underlying class uniquely;
-@item The @code{Object} is a kind of container that has the ability to aggregate other @code{Objects} using the method @code{AggregateObject};
-@item The @code{Object} exports a method called @code{GetObject} that allows for discovery of other aggregated @code{Objects}.
-@end itemize
-
-@cindex base class
-@cindex Object
-It is crucially important to understand what we have described here
-(especially for those coming from other systems that provide similar
-functionality). A given C++ class has an object access interface that is
-essentially the collection of method signatures specified in its inheritance
-tree. This is a C++ object model thing. Ns-3 provides a base class from
-which the class in question can inherit and be promoted to the status of
-@code{Object}. Once a class becomes an @code{Object} it has inherited the
-ability to aggregate and search for other @code{Objects} that are added to
-its aggregation.
-
-That last detail is important. In @command{ns-3} @code{Objects} are both
-containers and specifications for a object method access. We have previously
-mentioned that the @code{Node} class acts as a container. In fact, the
-@code{Node} class inherits from @code{Object} and is itself an @command{ns-3}
-@code{Object}. So, when the @code{Node} object is created it is really an
-aggregation of one @code{Object} and you can call @code{AggregateObject} or
-@code{GetObject} on the resulting @code{Node} object. Along with being an
-aggregation, the @code{Node} class also describes a public interface. THis
-public interface (API) is declared just as any C++ object is declared, via its
-class methods as specified in the inheritance tree. For those steeped in
-COM or CORBA, this is where the concept of Interface works in @command{ns-3}.
-Remember that it is generally true that @code{Objects} are both aggregations
-and APIs.
-
-@subsection Aggregations
-@cindex aggregate
-The figure below shows how an @code{Object} could be illustrated in detail.
-The line with the circle at the top of the diagram represents the appearance
-of the @code{Object} API to the external world. This circle and line are
-together called a lollipop because of its superficial similarity to a kind of
-childs candy.
-
-@sp 1
-@center @image{oneobj,,,,png}
-
-@cindex API
-You could declare this API and associated @code{Object} quite simply using a
-non-virtual class as follows,
-
-@verbatim
- class A : public Object {
- public:
- static ns3::TypeId GetTypeId (void)
- {
- static ns3::TypeId tid = ns3::TypeId ("A")
- .SetParent (Object::GetTypeId ())
- .AddConstructor<A> ();
- return tid;
- }
-
- A ()
- {
- }
-
- void MethodA (void);
- };
-@end verbatim
-
-The methods that are then available via the API labeled @code{A} in the
-figure above are the methods inherited from the @code{Object} base class
-(@code{GetObject}, @code{Ref}, and @code{Unref}) and those from class
-@code{A} (@code{MethodA}).
-
-Note that you must declare a @code{TypeId} in your @code{Object} class, and
-it must be declared static to make it class-wide in scope. This @code{TypeId}
-is a unifying element in the @command{ns-3} object model and uniquely
-identifies @code{Objects} at run-time as being instantiated from a particular
-class. We'll have much more to say about @code{TypiId} shortly.
-
-You can think of the arc and arrow device coming off each side of the
-illustrated @code{Objects} as part of a connector. These connectors allow
-@code{GetObject} to search aggregations for an instance of a class type.
-The figure below shows an aggregation of three @code{Objects}: A, B and C.
-The class declarations for classes @code{B} and @code{C} are substantially
-similar to that of class @code{A}.
-
-@sp 1
-@center @image{threeobj,,,,png}
-
-You can visualize these @code{Objects} as being snapped together like Lego
-building blocks if you like. When @code{Objects} are aggregated, a
-@code{GetObject} search path is formed through the connectors. In order
-to create this aggregation you will first need to create the @code{Objects}.
-These are just normal, everyday C++ objects that we can create using the
-@code{CreateObject} template function and manage using smart pointers. The
-following code should be obvious to you by now:
-
-@verbatim
- Ptr<A> a = CreateObject<A> ();
- Ptr<B> b = CreateObject<B> ();
- Ptr<C> c = CreateObject<C> ();
-@end verbatim
-
-@cindex aggregation
-When you create an aggregation, you pick one of the @code{Objects} of the
-aggregation to think of as the container. In this case well pick @code{Object}
-A. In order to aggregate an @code{Object}, you simply call the method
-@code{AggregateObject} that your class has inherited from class @code{Object}.
-The following code will aggregate @code{Object B} and @code{Object C} onto
-the @code{Object} (and container/aggregation) @code{A}.
-
-@cindex AggregateObject
-@cindex GetObject
-@cindex Object
-@verbatim
- a->AggregateObject (b);
- a->AggregateObject (c);
-@end verbatim
-
-Thats all there is to it. Now that you have those connectors snapped
-together, you can ask each of the @code{Objects} in the aggregation for any of
-the other @code{Objects} in the aggregation. Lets look at a simple example:
-
-@verbatim
- Ptr<B> newB = a->GetObject<B> ();
-@end verbatim
-
-Now, the explanation of what this snippet does is not as simple as writing it.
-The left hand side of this assignment declares a smart pointer to the class
-@code{B} to help with memory management of the returned @code{Object} pointer.
-You should be very familiar with smart pointers at this stage of the tutorial.
-
-The right hand side illustrates how @code{GetObject} is acutally used.
-The method @code{GetObject} is templated. The assocated template parameter
-(between the brackets) specifies the @emph{class} that is being requested.
-This is important. Since it is the class type that specifies the search
-criteron, there can be only one instance of a particular class present in an
-aggregation. Looking back a little, although the parameter to
-@code{AggregateObject} appears to be a vanilla C++ object (@code{b} or @code{c}
-above), it actually represents (is an instance of) a class that has an
-associated @code{TypeId} and inherits from @code{Object}. When you call
-@code{GetObject} you specify the search criterion (using the template
-parameter) as a class name. This referenced class must also have an
-associated @code{TypeId} and must also have inherited from @code{Object}.
-
-This may be summarized by saying that @code{AggregateObject} takes an
-@emph{instance} of an object of a particular class that inherits from
-@code{Object}. GetObject looks for a @emph{class} of a particular type
-(that again inherits from @code{Object}) and possibly returns an aggregated
-object instance of that type.
-
-Now that you have those conceptual connectors snapped together, you can ask
-each of the @code{Objects} in the aggregation for any of the @code{Objects}
-in the aggregation. For example we could walk the @code{Objects} asking each
-for the next in the aggregation. First we would ask the @code{Object} pointed
-to by the smart pointer @code{a} to look for the @code{Object} @code{class B}:
-
-@verbatim
- Ptr<B> newB = a->GetObject<B> ();
-@end verbatim
-
-Next, we can ask the @code{Object} pointed to by the smart pointer @code{newB}
-to look for the @code{Object} representing @code{class C}:
-
-@verbatim
- Ptr<C> newC = newB->GetObject<C> ();
-@end verbatim
-
-@cindex Object
-Then, we can ask the @code{Object} pointed to by the smart pointer @code{newC}
-to look for the @code{Object} representing @code{class A} and complete our
-circuit of the aggregation:
-
-@verbatim
- Ptr<A> newA = newC->GetObject<A> ();
-@end verbatim
-
-@cindex GetObject
-@code{GetObject} has some important properties that we need to go over.
-Technically, @code{GetObject} is a @emph{symmetric}, @emph{reflexive} and
-@emph{transitive} operation with respect to the set of aggregated
-@code{Objects}.
-
-@subsubsection Symmetry
-@cindex symmetry
-The symmetric nature of @code{GetObject} guarantees that if one performs a
-@code{GetObject} on a given @code{Object} for the class of that same
-@code{Object}, that @code{GetObject} must succeed. In other words, the
-fact that you accessed the aggregation via an instance of an @code{Object A}
-in the aggregation implies the reachability of that @code{Object} in the
-aggregation. This is usually written (by Microsoft) as,
-
-@center must succeed (A >> A)
-
-We can illustrate this property with the code snippet,
-
-@verbatim
- Ptr<A> symmetricA = a->GetObject<A> ();
- NS_ASSERT (symmetricA);
-@end verbatim
-
-Here we take as given an interface (smart) pointer --- named @code{a} --- on
-which we perform a @code{GetObject} looking for the class that represents that
-same @code{Object}. This call must always succeed and a smart pointer to the
-aggregated instance of that class is returned.
-
-@subsubsection Reflexivity
-@cindex reflexivity
-Calls to @code{GetObject} must also be reflexive. This means that if you
-successfully @code{GetObject} for @code{Object B} from @code{Object A}, then
-you must always be able to @code{GetObject} for @code{A} from @code{B}. This
-is usually written as,
-
-@center must succeed (A >> B, then B >> A)
-
-This property can be illustrated with the code snippet,
-
-@verbatim
- Ptr<B> b = a->GetObject<B> ();
- Ptr<A> reflexiveA = b->GetObject<A> ();
- NS_ASSERT (reflexiveA);
-@end verbatim
-
-If the first @code{GetObject} on @code{Object A} looking for @code{Object B}
-succeeds, then a @code{GetObject} on @code{Object B} looking @code{Object A}
-must succeed.
-
-@subsubsection Transitivity
-@cindex transitivity
-@code{GetObject} must also be transitive. This means that if one can
-find @code{Object B} from @code{Object A}, and @code{Object C} from
-@code{Object B}, then one must also be able to find @code{Object C} from
-@code{Object A}. This is usually written as,
-
-@center must succeed (A >> B, and B >> C, then A >> C)
-
-This property can be illustrated with the code snippet,
-
-@verbatim
- Ptr<B> b = a->GetObject<B> ();
- Ptr<C> c = b->GetObject<C> ();
- Ptr<C> transitiveC = a->GetObject<C> ();
- NS_ASSERT (transitiveC);
-@end verbatim
-
-If you can get to @code{Object B} from @code{Object A}, and you can get to
-@code{Object C} from @code{Object B}, then a @code{GetObject} on
-@code{Object A} looking for @code{Object C} must also succeed.
-
-@subsection Creating the TypeId
-@cindex TypeId
-@cindex GetTypeId
-The final piece of this puzzle is the @code{TypeId}. Recall that the
-declaration our eample object above included the following code
-
-@verbatim
- static ns3::TypeId GetTypeId (void)
- {
- static ns3::TypeId tid = ns3::TypeId ("A")
- .SetParent (Object::GetTypeId ())
- .AddConstructor<A> ();
- return tid;
- }
-@end verbatim
-
-This is the bit of code that ties this all together. For those unfamiliar
-with the idioms involved, this declaration can be rather dense. First, let's
-examine the function declaration itself. The following code,
-
-@verbatim
- static ns3::TypeId GetTypeId (void) ...
-@end verbatim
-
-declares a function that will be associated with all of the instances of the
-given class. This is a function, not a method, in that it can be accessed
-without a @emph{this} pointer; but it is associated with the class in a
-namespace sense. The use of this kind of declaration allows one to write,
-
-@verbatim
- return A::GetTypeId (void);
-@end verbatim
-
-if the @code{TypeId} is needed for our @code{class A}. More generically the
-class name can be substituted in a template, as is done deep in the
-@command{ns-3} object system.
-
-From this perspective, if you leave out the middle of the function definition,
-the boundaries should make sense to you.
-
-@verbatim
- static ns3::TypeId GetTypeId (void)
- {
- return tid;
- }
-@end verbatim
-
-@cindex function-local variable
-You are obviously looking at a global function associated with your class
-that simply returns a @code{TypeId}. Now, what about the rest. The code
-
-@verbatim
- static ns3::TypeId tid = ns3::TypeId ("A")
- .SetParent (Object::GetTypeId ())
- .AddConstructor<A> ();
-@end verbatim
-
-when found inside the function declaration is called a function-local variable
-with associated initialization. It'll be easier to pick this statement apart
-piece by piece as well. The first line,
-
-@verbatim
- static ns3::TypeId tid = ...
-@end verbatim
-
-is the declaration of the function-local variable tid. This is essentially
-an initialized global variable, the scope of which has been reduced to within
-the enclosing method. You can think of this as a kind of global variable
-that can only be accessed right there where it is created. If the variable
-is initialized, this amounts to the same behavior as if a global static
-initializer was declared in a namespace of the same name as your class.
-Global static initializers are guaranteed by the C++ language definition to
-be executed before your main procedure is entered. So are function-local
-variables.
-
-The variable that is being initialized is of type @code{ns3::TypeId}, is
-named @code{A::tid} since it is inside the class declaration for
-@code{class A}, and is initialized by a call to the constructor for the class
-@code{TypeId}. The constructor for @code{TypeId} takes a @code{std::string}
-that can be used to locate the type information for your class. We usually
-privide the class name as the string.
-
-Hopefully, this much of the declaration is now clear:
-
-@verbatim
- static ns3::TypeId GetTypeId (void)
- {
- static ns3::TypeId tid = ns3::TypeId ("A")
- ...
- return tid;
- }
-@end verbatim
-
-All that is left now are the lines including @code{SetParent} and
-@code{AddConstructor}.
-
-@verbatim
- static ns3::TypeId tid = ns3::TypeId ("A")
- .SetParent (Object::GetTypeId ())
- .AddConstructor<A> ();
-@end verbatim
-
-The last bit may seem quite odd at first glance, but don't let the way the
-code is broken up over several lines throw you. If you saw something like,
-
-@verbatim
- pointer->TypeId()->SetParent()->AddConstructor();
-@end verbatim
-
-you probably wouldn't hesitate at all. Clearly, you would think, a method
-called @code{TypeId} is called using the pointer called @code{pointer} as
-shown below.
-
-@verbatim
- pointer->TypeId()
-@end verbatim
-
-The method @code{TypeId} must further return a pointer to an object that has
-a method called @code{SetParent}. Just as clearly, @code{SetParent} must
-return a pointer to an object that has a method called @code{AddConstructor}.
-The same sort of thing is happening in our code snipped, except we are using
-references instead of pointers. Perhaps if we rearrange this code to live on
-one line it will be clearer.
-
-@verbatim
- ns3::TypeId ("A").SetParent (Object::GetTypeId ()).AddConstructor<A> ();
-@end verbatim
-
-It's just a string of method calls. The remaining question is then, what do
-those three methods do.
-
-The first, @code{ns3::TypeId ("A")}, simply allocates a new type in the system
-and allows you to refer to it in the future by a string. We have mentioned
-inheritance trees often in the previous discussion. The second method,
-@code{SetParent} associates the class being defined with its parents in the
-tree. Finally, the @code{AddConstructor} method allows you to specify a
-constructor to be used when an instance of your class is created using
-@code{CreateObject}.
-
-@verbatim
- AddConstructor<A> ();
-@end verbatim
-
-You can interpret this as explaining to the @command{ns-3} object ssytem that
-you have a constructor named @code{A::A} which takes no parameters. You are
-saying that this constructor should be used when @code{CreateObject} is called
-with no parameters.
-
-By including the structure of the inheritance tree, in @command{ns-3} we can
-use implementation inheritance to easily create new @code{Objects}. You are
-prevented from doing so in Microsoft COM, but this was almost universally
-identified as a problem.
-
-So, looking at the entire @code{GetTypeId} declaration again,
-
-@verbatim
- static ns3::TypeId GetTypeId (void)
- {
- static ns3::TypeId tid = ns3::TypeId ("A")
- .SetParent (Object::GetTypeId ())
- .AddConstructor<A> ();
- return tid;
- }
-@end verbatim
-
-it should be clear what is happening.
-
-@subsection A Very Real Example
-@cindex Node
-@cindex AggregateObject
-@cindex GetObject
-@cindex Object
-At this point you may be asking yourself what the point of all of this is,
-since you already had those pointers laying around when you created the
-objects. The typical case is that one will create and aggregate some number
-of @code{Objects} in a constructor and return only a pointer to a single
-@code{Object} as in our canonical example with @code{class Node}. In this
-case, the @code{Node} would be created and the @code{Node} constructor might
-create and call @code{AggregateObject} to aggregate the @code{Objects} for
-internetwork routing and TCP/IP. From an external point of view, these
-aggregated objects may be discovered at run-time using @code{GetObject}.
-
-Generally one tends to think of one of the @code{Objects} in the aggregation
-as being the container and other @code{Objects} being aggregated to that
-container. In the case of a Node, for example, it is quite natural to think
-of the Node as being the container which contains protocol stacks, internet
-routing, etc. So, lets start thinking about a real example by calling the
-container @code{Object Node} instead of @code{A} as we have been. The
-creation of this @code{Object} is found all over our example programs. For
-example, you will find code like the following in
-@code{samples/simple-point-to-point.cc}:
-
-@verbatim
- Ptr<Node> n = CreateObject<InternetNode> ();
-@end verbatim
-
-It may appear obvious to you now that the @code{InternetNode} class name
-provided to the template function @code{CreateObject} means that
-@code{InternetNode} is an @command{ns-3} @code{Object} and you will be able to
-call @code{GetObject} on the resulting smart pointer. Well, I'm afraid that's
-not entirely true. It's slightly more complicated.
-
-Take a look at @code{src/internet-stack/internet-stack.h} and find the class
-declaration for @code{InternetNode}.
-
-@verbatim
- class InternetNode : public Node
- {
- public:
- InternetNode();
- ...
- };
-@end verbatim
-
-@cindex GetTypeId
-@cindex TypeId
-@cindex Object
-There is no declaration of a @code{static TypeId GetTypeId (void)} in this
-class. This means that the @code{InternetNode} is really not an @code{Object}
-for which you can @code{GetObject}. It turns out that the @code{InternetNode}
-is an @emph{implementation class} of the @code{Node Object}.
-
-You may recall that there can be an implicit cast in a smart pointer
-assignment if the cast is to a visible, unambiguous base class. That is, in
-fact, what is happening here. Now, take a look at @code{src/node/node.h} and
-find the class declaration for @code{class Node}. There you will find,
-
-@verbatim
- class Node : public Object
- {
- public:
- static TypeId GetTypeId (void);
- ...
- };
-@end verbatim
-
-Class @code{InternetNode} inherits from class @code{Node} that, in turn,
-inherits from class @code{Object}. It is @code{Node} that provides a
-@code{GetTypeId} method. Therefore it is @code{Node} that is an
-@command{ns-3} @code{Object}. Note well that @code{InternetNode} is not an
-@code{Object} in the sense that one should call @code{GetObject} on an
-aggregation looking for an @code{InternetNode} class. That is, you should not
-do,
-
-@verbatim
- Ptr<InternetNode> i = node->GetObject<InternetNode> ();
-@end verbatim
-
-since there really is not InternetNode::GetTypeId. It is @code{Node} that is
-the @emph{proper} @code{Object} in this case and you should view
-@code{InternetNode} as an implementation of the @code{Node Object}. This may
-become clearer as we look a little deeper.
-
-We spoke of a protocol stack that is aggregated to a @code{Node} in our
-discussions above, what we see in the real @command{ns-3} code is that this
-is represented by the @code{Ipv4 Object}. If you look in
-@code{src/node/ipv4.h} you will find,
-
-@verbatim
- class Ipv4 : public Object
- {
- public:
- static TypeId GetTypeId (void);
- ...
- };
-@end verbatim
-
-Since class @code{Ipv4} inherits from class @code{Object} and has a
-@code{GetTypeId}, it is an @command{ns-3} @code{Object}. If you look in
-@code{src/node/ipv4.cc} you will find,
-
-@verbatim
-TypeId
-Ipv4::GetTypeId (void)
-{
- static TypeId tid = TypeId ("Ipv4")
- .SetParent<Object> ();
- return tid;
-}
-@end verbatim
-
-After all of this reading you know that this code snippet is asking the
-system to create a unique @code{TypeId} for the @code{Ipv4} class and
-declares that @code{Ipv4} inherits from class @code{Object}. This is what
-makes an @code{Ipv4} an @code{Object}.
-
-@cindex Ipv4
-It turns out that the Ipv4 class is an abstract base class (ABC). There are
-a number of pure virtual methods declared in that class. This means that
-an @code{Ipv4} object may not be instantiated. This is reflected by the fact
-that there are no constructors registered in the @code{GetTypeId} method above.
-What is instantiated in the real system is an implementation class, called
-@code{Ipv4Impl}. This class inherits from @code{Ipv4} and provides the
-required virtual methods. This is where understanding what is an
-@code{Object} and what is not can get tricky. The @code{Object} is the
-@code{Ipv4} class since that is where the @code{GetTypeId} is found. The fact
-that you see @code{GetTypeId} there tells you that the @code{Ipv4} class is
-the class for which you can @code{GetObject}.
-
-@cindex implementation class
-The class @code{Ipv4Impl} provides an implementation for the pure virtual
-methods in @code{Ipv4}. Since class @code{Ipv4} cannot be instantiated, one
-instantiates the @code{Ipv4Impl} class to create an @code{Ipv4} @code{Object}.
-You will use the @code{CreateObject} template function to create an object that
-implements the methods of an @code{Object}. You can probably see how this
-gets even more tricky in conversation.
-
-Once the @code{Ipv4Impl} object is instantiated, the resulting pointer is
-immediately cast to an @code{Ipv4} pointer. Clients will then use the
-methods specified in the @code{Ipv4} class to access the @code{Ipv4 Object}
-methods which are, in turn, implemented in the @code{Ipv4Impl} object.
-
-If you now look in the file, @code{src/internet-stack/internet-stack.cc} you
-will see the following code in @code{InternetNode::Construct} that creates the
-@code{Ipv4} Interface and aggregates it.
-
-@verbatim
- Ptr<Ipv4Impl> ipv4Impl = CreateObject<Ipv4Impl> (ipv4);
- ...
- Object::AggregateObject (ipv4Impl);
-@end verbatim
-
-Note that the parameter @code{ipv4} passed to the @code{CreateObject} template
-function is actually a pointer to an @code{Ipv4L3Protocol} which you can
-ignore at this point --- it doesn't really have anything to do with the
-@code{Ipv4} Interface.
-
-This is exactly the same thing that is happening in the case of the
-@code{InternetNode}.
-
-@verbatim
- Ptr<Node> n = CreateObject<InternetNode> ();
-@end verbatim
-
-@cindex implementation object
-@code{CreateObject} is being called to create an implementation object,
-in this case @code{InternetNode}, which implements the methods of the
-@code{Node Object}. It is the resulting @code{Node Object} which you would
-use as the container and it is the @code{Node} class that you would use as
-the template parameter when calling @code{GetObject}. In the same way, you
-would @emph{not} want to do,
-
-@verbatim
- Ptr<Ipv4> ipv4 = node->GetObject<Ipv4Impl> ();
-@end verbatim
-
-Rather you should understand that the @emph{proper} @code{Object} is the
-@code{Ipv4} not the @code{Ipv4Impl} and do the following,
-
-@verbatim
- Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
-@end verbatim
-
-@cindex CreateObject
-This does illustrate that the fact that whether an object created by
-@code{CreateObject} is or is not an @code{Object} in the usual sense can be
-quite well hidden if you are casually looking at the object creation code.
-The designers of the system had long and involved discussions on this issue
-and in the end decided that mnemonic aids such as Hungarian notation were a
-stylistic thing and you should just refer to the system documentation to
-determine what objects are @command{ns-3} @code{Objects} and what the APIs
-of those @code{Objects} actually are (RTFM --- as in Read the Fine Manual,
-of course).
-
-@cindex AggregateObject
-@cindex Object
-In the case of @code{Ipv4Impl}, you know that the class inherits somehow
-from @code{Object} since there is a call to @code{AggregateObject} that
-refers to an instance of an @code{Ipv4Impl}. You will have to go to
-the header file @code{src/internet-stack/ipv4-impl.h} and find that
-@code{Ipv4Impl} inherits from class @code{Ipv4}. You will then have go to
-the file @code{src/node/ipv4.h} and see that it inherits from @code{Object} and
-defines a @code{GetTypeId}. Thus the @code{Object} for which you can
-@code{GetObject} is really the @code{Ipv4 Object}.
-
-Returning to some real @command{ns-3} example code, lets take a look at
-@code{examples/simple-point-to-point.cc}. You will find the following
-code in this file:
-
-@verbatim
- Ptr<Node> n0 = CreateObject<InternetNode> ();
- ...
- Ptr<Ipv4> ipv4;
- ipv4 = n0->GetObject<Ipv4> ();
- ipv4->SetDefaultRoute (Ipv4Address (``10.1.1.2''), 1);
-@end verbatim
-
-@cindex InternetNode
-@cindex Node
-@cindex Object
-@cindex GetObject
-The first line creates an @code{InternetNode} implementation object and casts
-the resulting smart pointer to a @code{Node} as we have discussed extensively.
-The next line shown declares a smart pointer to an @code{Ipv4 Object}. We
-then do a @code{GetObject} on the @code{Node} looking for the
-@code{Ipv4 Object}. You know since you've read every line of this tutorial
-in detail exactly how that @code{Ipv4 Object} got into every @code{Node}. You
-know that the @code{GetObject} will return a smart pointer to its aggregated
-@code{Ipv4} Interface. Once we have the @code{Ipv4} smart pointer, we simply
-use it as if it were any other C++ object. The last line shows this by
-setting the default route for the node.
-
-@section Caveats
-There are a few things that you should remember but which may not be
-immediately obvious.
-
-@subsection Ns-3 Objects are Associated with Classes not C++ objects
-@cindex Object
-@cindex GetObject
-@cindex iterate
-@cindex aggregation
-@cindex GetNDevices
-Okay, you can see some of the problems with the terminology popping up again.
-We are reminding you that when you do a GetObject you are providing the key
-to the lookup by giving a class name and not anything that is unique to a
-C++ object.
-
-You cannot add more than one @code{Object} of a given type (class name) to an
-aggregation. If you need to contain a number of @code{Objects} of the same
-type in the same aggregation, you will need to provide a separate container
-over which you can iterate. For example, the @code{Node} class provides
-methods,
-
-@verbatim
- uint32_t GetNDevices (void) const;
- Ptr<NetDevice> GetDevice (uint32_t index) const;
-@end verbatim
-
-that are used iterate over the multiple @code{NetDevice} @code{Objects}
-associated with it.
-
-@emph{Remember: Object types do not identify objects.}
-
-@subsection Dont use GetObject to Check Your Own Type.
-@cindex GetObject
-It is tempting to use @code{GetObject} as a form of runtime type
-information. Dont do it. You have no control over what @emph{other}
-object may be added to your aggregation. Someone else may have
-appropriated (reimplemented) your type and aggregated themselves onto the
-aggregation.
-
-Consider a socket factory implementation. Sockets can be either UDP sockets
-or TCP sockets. A socket factory will have a generic @code{SocketFactory}
-Object and either a UDP specific interface for setting UDP parameters or a
-similar TCP-specific interface.
-
-Consider what might happen if you declared your socket factory as a partially
-abstract base class, and then provided separate implementations for UDP and
-TCP specific methods of this factory in separate concrete classes. Now
-consider what might happen if you used @code{GetObject} in your base class
-to determine if you were a UDP or a TCP factory.
-
-If a factory, say the UDP version, were not aggregated to any other
-@code{Object}, the base class could @code{GetObject} on itself for the
-UDP-specific class name. If the @code{GetObject} succeeded, it could then
-infer that it was a UDP implementation and would then do any UDP-specific
-tasks it could. [Experienced C++ folks are cringing about how
-horrible this design is, but bear with me --- its a simple illustration of
-a specific and perhaps not-too-obvious problem.]
-
-If another factory, say the TCP version, were not aggregated to any other
-Interface, the base class could @code{GetObject} on itself for the UDP-specific
-interface. If this failed, it could then infer that it had a TCP
-implementation and would then do any TCP-specific tasks it could.
-
-Now, what happens when these two working objects are aggregated together by
-some innocent end-user. Since the @code{Objects} are conceptually snapped
-together, the TCP implementation would suddenly begin finding the UDP
-Interface from the other class factory and think it was the UPD implementation.
-
-@emph{Objects should not be used as run-time type information.}
-
-@section Connecting the Dots
-@cindex Object
-@cindex GetObject
-@cindex AggregateObject
-@cindex GetTypeId
-@cindex API
-This may all sound very complicated to you if this is your first exposure to
-these concepts. It may be annoying if I tell you that its really not as hard
-as it sounds. Rest assured that if you take some time, look at and understand
-the examples and write a little test code it will all come together for you.
-Grep around the system for @code{AggregateObject} and @code{GetObject} and
-take a look at how we have used them. This will also give you a good idea of
-what our core @code{Objects} and associated APIs are. If you grep for
-@code{GetTypeId} you will find most, if not all of the @code{Object} API
-interface declarations in the system. The more you see this idiom in
-use, the more comfortable you will be with the idea and the more you will see
-how this addresses the weak base class, swiss army knife base class, and
-fragile base class problems I explained at the beginning.
-
-As I alluded to earlier, the developers had long discussions regarding how to
-make navigating the @code{Object} environment easier. The primary issue was
-how we could make it easier to convey to you, the model writer, that an object
-was an @code{Object}. We originally used similar terminology as Microsoft
-COM and used QueryInterface instead of @code{GetObject}. One suggestion was
-to adopt the convention that classes that implemented Interfaces must begin
-with the letter I. Microsoft does this, as exemplified by the class IUnknown.
-We also toyed with the idea of beginning our header files with ``i-'' as in
-``i-ipv4.h.'' We considered forcing some structure on Interfaces with a pure
-virtual class specification, the names of which begin with an I; and
-corresponding implementations, the names of which begin with a C. This all
-got out of hand fairly quickly.
-
-In the end we decided that we were really discussing issues of programming
-style, and we really could not come up with a strong reason to impose any
-particular solution. No matter what direction we took, we ended up with some
-form of extra confusion or extra complexity somewhere in the system. The
-resulting system is extremely flexible and easy to use. It is, unfortunately,
-sometimes hard to document and talk about.
-
-@cindex Feynman
-If it helps you to think in terms of Microsoft COM and Interfaces, by all means
-do so, just be aware that even though @command{ns-3} @code{Objects} descend
-from COM in some sense, there are subtle differences that may get you lost or
-into trouble. So to paraphrase Feynman one more time,
-
-@quotation
-``@command{Ns-3} @code{Objects} do not behave like COM Components, or Java
-Beans, or CORBA objects, or clouds or weights on springs, or like anything
-that you have ever seen --- they are @command{ns-3} components.''
-@end quotation
-
-Just get very familiar with the @command{ns-3} object model. It is the heart
-of the system and if you do not understand it you will not understand how to
-write an @command{ns-3} model properly.
-
-@c ========================================================================
-@c Doxygen
-@c ========================================================================
-
-@node The-Doxygen-Documentation-System
-@chapter The Doxygen Documentation System
-
-@node How-To-Change-Things
-@chapter How to Change Things
-
-@node How-To-Set-Default-Values
-@chapter How to Set Default Values
-
-@node How-To-Write-A-New-Application
-@chapter How to Write a New Application
-
--- a/doc/tutorial/output.texi Sat Jun 28 19:39:46 2008 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,462 +0,0 @@
-
-@c ========================================================================
-@c Simulation Output
-@c ========================================================================
-
-@node Simulation Output
-@chapter Simulation Output
-
-At this point, you should be able to execute any of the built-in
-programs distributed with @command{ns-3}. Next, we will look at
-how to generate and tailor the simulation output, before turning
-to how to modify simulation scripts to do different things.
-
-@node Tracing Basics
-@section Tracing Basics
-
-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 goal of the @command{ns-3} tracing system is to
-provide a structured way to configure the simulator to output results
-in standard or modifiable formats.
-@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 will 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 fundamentally built on the
-concept of separating tracing sources from sinks.
-@enumerate
-@item Trace sources (e.g., provide access to every packet received)
-@item Trace sinks (e.g., print out the packet)
-@item A mechanism to tie together sources and sinks
-@end enumerate
-The rationale for this division is to allow users to attach new
-types of sinks to existing tracing sources, without requiring
-users to edit and recompile the core of the simulator.
-Thus, in the example above, a user could write a new tracing sink
-and attach it to an existing tracing source. What remains to
-be defined is a way for users to find these hooks (tracing sources)
-and attach sinks to them. A new tracing namespace is defined for
-this purpose.
-
-We will first walk through how some pre-defined sources and sinks
-are provided and may be customized with little user effort. We
-return later in this chapter to advanced tracing configuration including
-extending the tracing namespace and creating new tracing sources.
-
-@subsection ASCII tracing
-@cindex ASCII
-For Internet nodes, the ASCII trace wrapper is a wrapper around
-the @command{ns-3} low-level
-tracing system that lets you get access to underlying trace events easily.
-The output of a trace of a simulation run is an ASCII file --- thus the name.
-In the spririt of keeping things simple, you won't be able to control or
-configure the output at this stage.
-
-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. As usual, we need to include the definitions
-related to using ASCII tracing (don't edit any files quite yet):
-
-@verbatim
- #include "ns3/ascii-trace.h"
-@end verbatim
-
-We then need to add the code to the script to actually enable the ASCII tracing
-code. The following code must be inserted before the call to
-@code{Simulator::Run ();}:
-
-@verbatim
- AsciiTrace asciitrace ("tutorial.tr");
- asciitrace.TraceAllQueues ();
- asciitrace.TraceAllNetDeviceRx ();
-@end verbatim
-
-The first line declares an object of type @code{AsciiTrace} named
-@code{asciitrace} and passes a string parameter to its constructor. This
-parameter is a file name to which all of the trace information will be written.
-The second line, @code{asciitrace.TraceAllQueues ();} asks the trace object to
-arrange that all queue operations (enqueue, dequeue, drop) on the queues
-in all of the nodes of the system be traced. On the receive side,
-@code{asciitrace.TraceAlllNetDeviceRx ()} traces packets received by
-a NetDevice. For those familiar with @command{ns-2}, these are equivalent
-to the popular trace points that log "+", "-", "d", and "r" events.
-
-Try running the following program from the command line:
-@verbatim
- ./waf --run tutorial-csma-echo-ascii-trace
-@end verbatim
-
-@cindex tutorial.tr
-Just as you have seen previously, you will see some messages from @emph{Waf}
-and then the ``Compilation finished successfully'' message. The
-next message, @code{UDP Echo Simulation} is from the running program. When
-it ran, the program will have created a file named @code{tutorial.tr}.
-Because of the way that Waf works, the file is not created in the local
-directory, it is created at the top-level directory of the repository. So,
-change into the top level directory and take a look at the file
-@code{tutorial.tr} in your favorite editor.
-
-@subsubsection Parsing Ascii Traces
-@cindex parsing ascii traces
-
-This section parses in detail the structure of the ascii tracing
-output. If you find this output format self explanatory (it
-resembles tcpdump output), you may skip to the next
-section on pcap tracing.
-
-@cindex trace event
-There's a lot of information there in a pretty dense form, but the first thing
-to notice is that there are a number of distinct lines in this file. It may
-be difficult to see this clearly unless you widen your windows considerably.
-Each line in the file corresponds to a @emph{trace event}. A trace event
-happens whenever specific conditions happen in the simulation. In this case
-we are tracing events on the @emph{device queue} present in every net device
-on every node in the simulation. The device queue is a queue through which
-every packet destined for a channel must pass --- it is the device
-@emph{transmit} queue. Note that each line in the trace file begins with a
-lone character (has a space after it). This character will have the following
-meaning:
-
-@cindex enqueue
-@cindex dequeue
-@cindex drop
-@itemize @bullet
-@item @code{+}: An enqueue operation occurred on the device queue;
-@item @code{-}: A dequeue operation occurred on the device queue;
-@item @code{d}: A packet was dropped, typically because the queue was full.
-@end itemize
-
-Let's take a more detailed view of the first line. I'll break it down into
-sections (indented for clarity) with a two digit reference number on the
-left side:
-
-@verbatim
- 00 +
- 01 2
- 02 nodeid=0
- 03 device=0
- 04 queue-enqueue
- 05 pkt-uid=9
- 06 ETHERNET
- 07 length/type=0x806,
- 08 source=08:00:2e:00:00:00,
- 09 destination=ff:ff:ff:ff:ff:ff
- 10 ARP(request
- 11 source mac: 08:00:2e:00:00:00
- 12 source ipv4: 10.1.1.1
- 13 dest ipv4: 10.1.1.2)
- 14 ETHERNET fcs=0
-@end verbatim
-
-@cindex trace event
-@cindex simulation time
-The first line of this expanded trace event (reference number 00) is the
-queue operation. We have a @code{+} character, so this corresponds to an
-@emph{enqueue} operation. The second line (reference 01) is the simulation
-time expressed in seconds. You may recall that we asked the
-@code{UdpEchoClient} to start sending packets at two seconds. Here we see
-confirmation that this is, indeed, happening.
-
-@cindex node number
-@cindex net device number
-@cindex smart pointer
-The next lines of the example listing (references 02 and 03) tell us that
-this trace event originated in a given node and net device. Each time a node
-is created it is given an identifying number that monotonically increases from
-zero. Therefore, @code{nodeid=0} means that the node in which the given trace
-event originated is the first node we created. In the case of our script,
-this first node is is the node pointed to by the smart pointer @code{n0}. Not
-too surpsisingly, this is also the node to which we attached the
-@code{UdpEchoClient}. The device number is local to each node, and so the
-device given by @code{device=0} is the first net device that we added to the
-node in question. In our simulation, this corresponds to the
-@code{CsmaNetDevice} we added to node zero (@code{n0}).
-
-@cindex uid
-@cindex unique ID
-@cindex packet
-The next line (reference 04) is a more readable form of the operation code
-seen in the first line --- i.e., the character @code{+} means
-@code{queue-enqueue}. Reference number 05 indicates that the @emph{unique id}
-of the packet being enqueued is @code{9}. The fact that the first packet we
-see has a unique ID of 9 should indicates to you that other things have
-happened in the protocol stack before we got to this point. This will become
-clear momentarily.
-
-@cindex Ethernet
-@cindex MAC address
-Reference items 06 and 14 indicate that this is an Ethernet packet with
-a zero (not computed) checksum (note the indentation to make parsing this
-trace event a little easier). Reference 08 and 09 are the source and
-destination addresses of this packet. The packet is from the MAC address we
-assigned to the node zero net device in the script, and is destined for the
-broadcast address --- this is a broadcast packet.
-
-@cindex Address Resolution Protocol
-@cindex ARP
-@cindex ARP|request
-Reference items 10 through 13 make clear what is happening. This is an ARP
-(Address Resolution Protocol) request for the MAC address of the node on
-which the @code{UdpEchoServer} resides. The protocol stack can't send a UDP
-packet to be echoed until it knows (resolves) the MAC address; and this trace
-event corresponds to an ARP request being queued for transmission to the local
-network. The next line in the trace file (partially expanded),
-
-@verbatim
- 00 -
- 01 2
- 02 nodeid=0
- 03 device=0
- 04 queue-dequeue
- 05 pkt-uid=9
- ...
-@end verbatim
-
-shows the (same) ARP request packet being dequeued from the device queue by
-the net device and (implicitly) being sent down the channel to the broadcast
-MAC address. We are not tracing net device reception events so we don't
-actually see all of the net devices receiving the broadcast packet. We do,
-however see the following in the third line of the trace file:
-
-@verbatim
- 00 +
- 01 2.00207
- 02 nodeid=1
- 03 device=0
- 04 queue-enqueue
- 05 pkt-uid=10
- 06 ETHERNET
- 07 length/type=0x806,
- 08 source=08:00:2e:00:00:01,
- 09 destination=08:00:2e:00:00:00,
- 10 ARP(reply
- 11 source mac: 08:00:2e:00:00:01
- 12 source ipv4: 10.1.1.2
- 13 dest mac: 08:00:2e:00:00:00
- 14 dest ipv4: 10.1.1.1)
- 15 ETHERNET fcs=0
-@end verbatim
-
-@cindex simulation time
-@cindex ARP|response
-Notice that this is a queue-enqueue operation (references 00 and 04) happening
-on node one (reference 02) at simulation time 2.00207 seconds (reference 01).
-Looking at the packet payload (references 10-14) we see that this is an ARP
-reply to the request sent by node one. Note that the simulation time
-(reference 01) is now 2.00207 seconds. This is direct result of the data rate
-(5 mb/s) and latency (2 ms) parameters that we passed to the
-@code{CsmaChannel} when we created it. Clearly the ARP request packet was
-sent over the channel and received approximately 2 ms later by node one. A
-corresponding ARP response packet was created and enqueued on node one's net
-device. It is this enqueue trace event that has being logged.
-
-@cindex queue
-@cindex queue|transmit
-@cindex echo
-Given the current state of affairs, the next thing you may expect to see is
-this ARP request being received by node zero, but remember we are only looking
-at trace events on the device @emph{transmit} queue. The reception of the ARP
-response by node zero will not directly trigger any trace event in this case,
-but it will enable the protocol stack to continue what it was originally doing
-(trying to send an echo packet). Thus, the next line we see in the trace file
-(@code{tutorial.tr}) is the first UDP echo packet being sent to the net device.
-
-@verbatim
- 00 +
- 01 2.00415
- 02 nodeid=0
- 03 device=0
- 04 queue-enqueue
- 05 pkt-uid=7
- 06 ETHERNET
- 07 length/type=0x800,
- 08 source=08:00:2e:00:00:00,
- 09 destination=08:00:2e:00:00:01
- 10 IPV4(
- 11 tos 0x0
- 12 ttl 64
- 13 id 0
- 14 offset 0
- 15 flags [none]
- 16 length: 1052) 10.1.1.1 > 10.1.1.2
- 17 UDP(length: 1032)
- 18 49153 > 7
- 19 DATA (length 1024)
- 20 ETHERNET fcs=0
-@end verbatim
-
-@cindex simulation time
-@cindex echo
-@cindex ARP
-@cindex ARP|request
-@cindex ARP|response
-@cindex IP
-@cindex Ipv4
-I won't go into too much detail about this packet, but I will point out a
-few key items in the trace. First, the packet was enqueued at simulation time
-of 2.00415 seconds. This time reflects the fact that the echo client
-application started at 2. seconds and there were two ARP packets transmitted
-across the network (two milliseconds + data transmission time each way). The
-packet unique identifier (reference 05) is 7. Notice that this is a lower
-number than the ARP request packet, which had a unique ID of 9. This tells
-us that the UDP packet was actually created before the ARP request packet ---
-which makes perfect sense since it was the attempt to send packet 7 that
-triggered sending the ARP request packet 9. Note that this an Ethernet
-packet (reference 06) like all other packets in this simulation, however this
-particular packet carries an IPV4 payload and therefore has an IP version 4
-header (indicated by references 10-16). This Ipv4 in turn contains a UDP
-header (references 17, 18) and finally 1024 bytes of data (reference 20).
-Clearly, this is the UDP echo packet emitted by the
-@code{UdpEchoClient Application}.
-
-The next trace event is an ARP request from node one. We can infer that node
-one has received the UDP echo packet and the @code{UdpEchoServer Application}
-on that node has turned the packet around. Just as node zero needed to ARP
-for the MAC address of node one, now node one must ARP for the MAC address of
-node zero. We see the ARP request enqueued on the transmit queue of node one;
-then we see the ARP request dequeued from the tranmit queue of node one (and
-implicitly transmitted to node zero). Then we see an ARP response enqueued
-on the transmit queue of node zero; and finally the ARP response dequeued (and
-implicitly transmitted back to node one).
-
-This exchange is summarized in the following trace event excerpts,
-
-@verbatim
- + 2.00786 nodeid=1 ... ARP(request ...
- - 2.00786 nodeid=1 ... ARP(request ...
- + 2.00994 nodeid=0 ... ARP(reply ...
- - 2.00994 nodeid=0 ... ARP(reply ...
-@end verbatim
-
-The final two trace events in the @code{tutorial.tr} file correspond to the
-echoed packet being enqueued for transmission on the net device for node one,
-and that packet being dequeued (and implicitly transmitted back to node zero).
-
-@cindex AsciiTrace!TraceAllNetDeviceRx
-@cindex ARP!request
-If you look at the trace file (@code{tutorial.tr}) you will also see some
-entries with an @code{r} event, indicating a
-@emph{receive} trace event. Recall that the first packet sent on the network
-was a broadcast ARP request. We should then see all four nodes receive a
-copy of this request. This is the case, as the first four receive trace
-events are,
-
-@verbatim
- r 2.00207 nodeid=0 device=0 dev-rx pkt-uid=9 ARP(request ...
- r 2.00207 nodeid=1 device=0 dev-rx pkt-uid=9 ARP(request ...
- r 2.00207 nodeid=2 device=0 dev-rx pkt-uid=9 ARP(request ...
- r 2.00207 nodeid=3 device=0 dev-rx pkt-uid=9 ARP(request ...
-@end verbatim
-
-@cindex unique ID
-You can see that a copy of the broadcast packet with unique ID 9 was received
-by the net devices on nodes 0, 1, 2 and 3. We leave it up to you to parse the
-rest of the trace file and understand the remaining reception events.
-
-@subsection PCAP Trace Wrapper
-@cindex pcap
-@cindex Wireshark
-The @command{ns-3} @emph{pcap trace wrapper} is used to create trace files in
-@code{.pcap} format. The acronym pcap (usually written in lower case) stands
-for @emph{p}acket @emph{cap}ture, and is actually an API that includes the
-definition of a @code{.pcap} file format. The most popular program that can
-read and display this format is Wireshark (formerly called Ethereal).
-However, there are many traffic trace analyzers that use this packet
-format, including X, Y, and Z. We encourage users to exploit the
-many tools available for analyzing pcap traces; below, we show how
-tcpdump and Wireshark can be used..
-
-@cindex tutorial-csma-echo-ascii-trace.cc
-@cindex tutorial-csma-echo-pcap-trace.cc
-The code used to enable pcap tracing is similar to that for ASCII tracing.
-We have provided another file, @code{tutorial-csma-echo-pcap-trace.cc} that
-uses the pcap trace wrapper. We have added the code to include the pcap
-trace wrapper defintions:
-
-@verbatim
- #include "ns3/pcap-trace.h"
-@end verbatim
-
-And then added the following code below the AsciiTrace methods:
-
-@cindex PcapTrace
-@cindex PcapTrace!TraceAllIp
-@verbatim
- PcapTrace pcaptrace ("tutorial.pcap");
- pcaptrace.TraceAllIp ();
-@end verbatim
-
-The first line of the code immediately above declares an object of type
-@code{PcapTrace} named @code{pcaptrace} and passes a string parameter to its
-constructor. This object is used to hide the details of the actual tracing
-subsystem. The parameter is a base file name from which the actual trace file
-names will be built. The second line of code tells the @code{PcamTrace}
-object to trace all IP activity in all of the nodes present in the simulation.
-
-@cindex interface index
-Trace files are not created until trace activity is detected. Each file name
-is composed of the base file name, followed by a @code{'-'}, a node id followed
-by a @code{'-}', and an IP interface index. You will soon see a file named
-@code{tutorial.pcap-0-1}, for example. This will be the trace file generated
-as events are detected on node zero, interface index one. N.B. Interface
-indices are different that net device indices --- interface index zero
-corresponds to the loopback interface and interface index one corresponds to
-the first net device you added to a node.
-
-You may run the new program just like all of the others so far:
-
-@cindex Waf
-@verbatim
- ./waf --run tutorial-csma-echo-pcap-trace
-@end verbatim
-
-If you look at the top level directory of your distribution, you should now
-see three log files: @code{tutorial.tr} is the ASCII trace file we have
-previously examined. @code{tutorial.pcap-0-1} and @code{tutorial.pcap-1-1}
-are the new pcap files we just generated. There will not be files
-corresponding to nodes two and three since we have not sent any IP packets to
-those nodes.
-
-@subsubsection Reading output with tcpdump
-@cindex tcpdump
-
-@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/}.
-
-If you have Wireshark available, you can open each of the trace files and
-display the contents as if you had captured the packets using a
-@emph{packet sniffer}. Note that only IP packets are traced using this
-wrapper, so you will not see the ARP exchanges that were logged when using
-the ASCII trace wrapper. You are encouraged to take a look at the contents
-of these pcap files using your favorite pcap software (or Wireshark).
-
-@node Advanced Tracing
-@section Advanced Tracing
-
--- a/doc/tutorial/statistics.texi Sat Jun 28 19:39:46 2008 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-@node Statistics
-@chapter Statistics
-@anchor{chap:Statistics}
-
-ns-3 does not presently have support for statistics (automatically generated
-statistical output). This is planned
-for development later in 2008. If you are interested in contributing,
-please see @uref{http://www.nsnam.org/wiki/index.php/Suggested_Projects,,our suggested projects page} or contact the ns-developers
-list.
--- a/doc/tutorial/troubleshoot.texi Sat Jun 28 19:39:46 2008 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +0,0 @@
-@node Troubleshooting
-@chapter Troubleshooting
-
-This chapter posts some information about possibly common errors in building
-or running ns-3 programs.
-
-Please note that the wiki (@uref{http://www.nsnam.org/wiki/index.php/Troubleshooting}) may have contributed items.
-
-@node Build errors
-@section Build errors
-
-@node Run-time errors
-@section Run-time errors
-
-Sometimes, errors can occur with a program after a successful build. These
-are run-time errors, and can commonly occur when memory is corrupted or
-pointer values are unexpectedly null.
-
-Here is an example of what might occur:
-
-@verbatim
-ns-old:~/ns-3-nsc$ ./waf --run tcp-point-to-point
-Entering directory `/home/tomh/ns-3-nsc/build'
-Compilation finished successfully
-Command ['/home/tomh/ns-3-nsc/build/debug/examples/tcp-point-to-point'] exited with code -11
-@end verbatim
-
-The error message says that the program terminated unsuccessfully, but it is
-not clear from this information what might be wrong. To examine more
-closely, try running it under the @uref{http://sources.redhat.com/gdb/,,gdb debugger}:
-
-@verbatim
-ns-old:~/ns-3-nsc$ ./waf --run tcp-point-to-point --command-template="gdb %s"
-Entering directory `/home/tomh/ns-3-nsc/build'
-Compilation finished successfully
-GNU gdb Red Hat Linux (6.3.0.0-1.134.fc5rh)
-Copyright 2004 Free Software Foundation, Inc.
-GDB is free software, covered by the GNU General Public License, and you are
-welcome to change it and/or distribute copies of it under certain conditions.
-Type "show copying" to see the conditions.
-There is absolutely no warranty for GDB. Type "show warranty" for details.
-This GDB was configured as "i386-redhat-linux-gnu"...Using host libthread_db library "/lib/libthread_db.so.1".
-
-(gdb) run
-Starting program: /home/tomh/ns-3-nsc/build/debug/examples/tcp-point-to-point
-Reading symbols from shared object read from target memory...done.
-Loaded system supplied DSO at 0xf5c000
-
-Program received signal SIGSEGV, Segmentation fault.
-0x0804aa12 in main (argc=1, argv=0xbfdfefa4)
- at ../examples/tcp-point-to-point.cc:136
-136 Ptr<Socket> localSocket = socketFactory->CreateSocket ();
-(gdb) p localSocket
-$1 = {m_ptr = 0x3c5d65}
-(gdb) p socketFactory
-$2 = {m_ptr = 0x0}
-(gdb) quit
-The program is running. Exit anyway? (y or n) y
-@end verbatim
-
-Note first the way the program was invoked-- pass the command to run as
-an argument to the command template "gdb %s".
-
-This tells us that there was an attempt to dereference a null pointer
-socketFactory.
-
-Let's look around line 136 of tcp-point-to-point, as gdb suggests:
-@verbatim
- Ptr<SocketFactory> socketFactory = n2->GetObject<SocketFactory> (Tcp::iid);
- Ptr<Socket> localSocket = socketFactory->CreateSocket ();
- localSocket->Bind ();
-@end verbatim
-
-The culprit here is that the return value of GetObject is not being
-checked and may be null.
-
-Sometimes you may need to use the @uref{http://valgrind.org,,valgrind memory
-checker} for more subtle errors. Again, you invoke the use of valgrind
-similarly:
-@verbatim
-ns-old:~/ns-3-nsc$ ./waf --run tcp-point-to-point --command-template="valgrind %s"
-@end verbatim
--- a/doc/tutorial/tutorial.texi Sat Jun 28 19:39:46 2008 -0700
+++ b/doc/tutorial/tutorial.texi Sat Jun 28 19:46:55 2008 -0700
@@ -66,7 +66,7 @@
@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 @@
@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
--- /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}.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/hello-simulator.cc Sat Jun 28 19:46:55 2008 -0700
@@ -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");
+}