--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/manual/Makefile Sun Jun 15 21:38:13 2008 -0700
@@ -0,0 +1,49 @@
+TEXI2HTML = texi2html
+TEXI2PDF = texi2dvi --pdf
+EPSTOPDF = epstopdf
+TGIF = tgif
+DIA = dia
+CONVERT = convert
+CSS = --css-include=manual.css
+SPLIT = --split section
+
+DIA_SOURCES = buffer.dia sockets-overview.dia
+TGIF_SOURCES = packet.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} manual.texi
+
+split-html: images
+ $(TEXI2HTML) ${CSS} ${SPLIT} manual.texi
+
+pdf: images
+ $(TEXI2PDF) manual.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 manual.aux manual.cp manual.cps manual.fn manual.ky manual.pg manual.tp manual.vr manual.toc manual.log manual.pdf manual.html manual/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/manual/attributes.texi Sun Jun 15 21:38:13 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/manual/callbacks.texi Sun Jun 15 21:38:13 2008 -0700
@@ -0,0 +1,330 @@
+@node ns-3 Callbacks
+@chapter ns-3 Callbacks
+
+Some new users to @command{ns-3} are unfamiliar with an extensively used
+programming idiom used throughout the code: the ``ns-3 callback''. This
+chapter provides some motivation on the callback, guidance on how to use
+it, and details on its implementation.
+
+@menu
+* Motivation::
+* Using the Callback API::
+* Callback locations in ns-3::
+* Implementation details::
+@end menu
+
+@node Motivation
+@section Motivation
+
+Consider that you have two simulation models A and B, and you wish
+to have them pass information between them during the simulation. One
+way that you can do that is that you can make A and B each explicitly
+knowledgable about the other, so that they can invoke methods on each
+other.
+
+@verbatim
+class A {
+public:
+ void ReceiveInput ( // parameters );
+ ...
+}
+
+(in another source file:)
+
+class B {
+public:
+ void ReceiveInput ( // parameters);
+ void DoSomething (void);
+ ...
+
+private:
+ A* a_instance; // pointer to an A
+}
+
+void
+B::DoSomething()
+{
+ // Tell a_instance that something happened
+ a_instance->ReceiveInput ( // parameters);
+ ...
+}
+@end verbatim
+
+This certainly works, but it has the drawback that it introduces a
+dependency on A and B to know about the other at compile time (this
+makes it harder to have independent compilation units in the simulator)
+and is not generalized; if in a later usage scenario, B needs to talk
+to a completely different C object, the source code for B needs to be
+changed to add a ``c_instance'' and so forth. It is easy to see that
+this is a brute force mechanism of communication that can lead to
+programming cruft in the models.
+
+This is not to say that objects should not know about one another
+if there is a hard dependency between them, but that often the model
+can be made more flexible if its interactions are less constrained at
+compile time.
+
+This is not an abstract problem for network simulation research,
+but rather it has been a source of problems in previous simulators,
+when researchers want to extend or modify the system to do different
+things (as they are apt to do in research). Consider, for example,
+a user who wants to add an IPsec security protocol sublayer
+between TCP and IP:
+@verbatim
+------------ -----------
+| TCP | | TCP |
+------------ -----------
+ | becomes -> |
+----------- -----------
+| IP | | IPsec |
+----------- -----------
+ |
+ -----------
+ | IP |
+ -----------
+@end verbatim
+If the simulator has
+made assumptions, and hard coded into the code, that IP always talks
+to a transport protocol above, the user may be forced to hack the
+system to get the desired interconnections.
+
+An alternative that provides this flexibility is to use a level of
+indirection that is commonly known in programming as a callback.
+A callback function is not invoked explicitly by the caller but is
+rather delegated to another function that receives the callback
+function's address and can call it.
+
+You may be familiar with function pointers in C or C++; these can
+be used to implement callbacks. For more information on introductory
+callbacks, an online reference is:
+@uref{http://www.inquiry.com/techtips/cpp_pro/10min/10min0300.asp,,Declaring Function Pointers and Implementing Callbacks} and
+@uref{http://en.wikipedia.org/wiki/Callback_(computer_science),,Callback (computer science)-- Wikipedia}.
+
+The callback API in @command{ns-3} is designed to minimize the overall
+coupling between various pieces of of the simulator
+by making each module depend on the callback API
+itself rather than depend on other modules. It acts as a sort of
+third-party to which work is delegated and which forwards this
+work to the proper target module. This callback API, being based
+on C++ templates,
+is type-safe; that is, it performs static type checks to enforce
+proper signature compatibility between callers and callees. It
+is therefore more type-safe to use than traditional function
+pointers, but the syntax may look imposing at first. This section
+is designed to walk you through the callback system so that you
+can be comfortable using it in @command{ns-3}.
+
+@node Using the Callback API
+@section Using the Callback API
+
+The Callback API is fairly minimal, providing only two services:
+@itemize @bullet
+@item callback type declaration: a way to declare a type of callback
+with a given signature, and,
+@item callback instantiation: a way to instantiate a
+template-generated forwarding callback which can forward any calls
+to another C++ class member method or C++ function.
+@end itemize
+
+This is best observed via walking through an example, based on
+@code{samples/main-callback.cc}.
+
+@node Using the Callback API with static functions
+@subsection Using the Callback API with static functions
+
+Consider a function:
+@verbatim
+static double
+CbOne (double a, double b)
+{
+ std::cout << "invoke cbOne a=" << a << ", b=" << b << std::endl;
+ return a;
+}
+@end verbatim
+
+Consider also the following main program snippett:
+@verbatim
+int main (int argc, char *argv[])
+{
+ // return type: double
+ // first arg type: double
+ // second arg type: double
+ Callback<double, double, double> one;
+}
+@end verbatim
+
+This class template Callback implements what is known as the Functor
+Design Pattern. It is used to declare the type of a callback. It contains
+one mandatory argument (the return type of the function to be assigned
+to this callback) and up to five optional arguments, which each specify
+the type of the arguments (if your function has more than five arguments,
+then this can be handled by extending the callback implementation).
+
+So in the above, we have a declared a callback named "one" that will
+eventually hold a function pointer. The function that it will hold
+must return double and must support two double arguments. If one
+tries to pass a function whose signature does not match the declared
+callback, the compilation will fail.
+
+Now, we need to tie together this callback instance and the actual
+target function (CbOne). Notice above that CbOne has the same function
+signature types as the callback-- this is important. We can
+pass in any such properly-typed function to this callback. Let's
+look at this more closely:
+@verbatim
+static double CbOne (double a, double b) {}
+ ^ ^ ^
+ | ---| ------|
+ | | |
+Callback<double, double, double> one;
+@end verbatim
+You can only bind a function to a callback if they have the matching
+signature. The first template argument is the return type, and the
+additional template arguments are the types of the arguments of
+the function signature.
+
+Now, let's bind our callback "one" to the function that matches its
+signature:
+@verbatim
+ // build callback instance which points to cbOne function
+ one = MakeCallback (&CbOne);
+@end verbatim
+
+Then, later in the program, if the callback is to be used, it can be
+used as follows:
+@verbatim
+// this is not a null callback
+ NS_ASSERT (!one.IsNull ());
+ // invoke cbOne function through callback instance
+ double retOne;
+ retOne = one (10.0, 20.0);
+@end verbatim
+
+The check @code{IsNull()} ensures that the callback is not null; that there
+is a function to call behind this callback. Then, @code{one()} returns the
+same result as if @code{CbOne()} had been called directly.
+
+
+@node Using the Callback API with member functions
+@subsection Using the Callback API with member functions
+
+Generally, you will not be calling static functions but instead
+public member functions of an object. In this case, an extra
+argument is needed to the MakeCallback function, to tell the system
+on which object the function should be invoked. Consider this example,
+also from main-callback.cc:
+
+@verbatim
+class MyCb {
+public:
+ int CbTwo (double a) {
+ std::cout << "invoke cbTwo a=" << a << std::endl;
+ return -5;
+ }
+};
+
+int main ()
+{
+ ...
+ // return type: int
+ // first arg type: double
+ Callback<int, double> two;
+ MyCb cb;
+ // build callback instance which points to MyCb::cbTwo
+ two = MakeCallback (&MyCb::CbTwo, &cb);
+ ...
+}
+@end verbatim
+
+Here, we pass a (raw) pointer to the @code{MakeCallback<>} function,
+that says, when @code{two ()} is invoked, to call the @code{CbTwo} function
+on the object pointed to by @code{&cb}.
+
+A variation of this is used when objects are referred to by ns-3 smart
+pointers. The MakeCallback API takes a raw pointer, so we need to
+call @code{PeekPointer ()} to obtain this raw pointer. So the example
+above would look like:
+
+@verbatim
+class MyCb : public Object {
+public:
+ int CbTwo (double a) {
+ std::cout << "invoke cbTwo a=" << a << std::endl;
+ return -5;
+ }
+};
+
+int main ()
+{
+ ...
+ // return type: int
+ // first arg type: double
+ Callback<int, double> two;
+ Ptr<MyCb> cb = CreateObject<MyCb> ();
+ // build callback instance which points to MyCb::cbTwo
+ two = MakeCallback (&MyCb::CbTwo, PeekPointer (cb));
+ ...
+}
+@end verbatim
+
+@node Building Null Callbacks
+@subsection Building Null Callbacks
+
+It is possible for callbacks to be null; hence it may be wise to
+check before using them. There is a special construct for a null
+callback, which is preferable to simply passing "0" as an argument;
+it is the @code{MakeNullCallback<>} construct:
+@verbatim
+ two = MakeNullCallback<int, double> ();
+ // invoking a null callback is just like
+ // invoking a null function pointer:
+ // it will crash at runtime.
+ //int retTwoNull = two (20.0);
+ NS_ASSERT (two.IsNull ());
+@end verbatim
+
+@node Callback locations in ns-3
+@section Callback locations in @command{ns-3}
+
+Where are callbacks frequently used in @command{ns-3}? Here are some of the
+more visible ones to typical users:
+
+@subsection Socket API
+@subsection Layer-2/Layer-3 API
+@subsection Tracing subsystem
+@subsection Routing
+Route Reply
+
+@node Implementation details
+@section Implementation details
+
+This section is advanced explanation for C++ experts interested in
+the implementation, and may be skipped by most users.
+
+This code was originally written based on the techniques described
+@uref{http://www.codeproject.com/cpp/TTLFunction.asp,,here}.
+It was subsequently rewritten to follow the architecture
+outlined in
+@uref{http://www.amazon.com/Modern-C\%2B\%2B-Design-Programming-Patterns/dp/0201704315/ref=pd_bbs_sr_1/102-0157303-1900156?ie=UTF8\&s=books\&qid=1187982662\&sr=1-1,,Modern C++ Design: Generic Programming and Design Patterns Applied-- Alexandrescu}, chapter 5, "Generalized Functors".
+
+This code uses:
+@itemize @bullet
+@item default template parameters to saves users from having to
+specify empty parameters when the number of parameters
+is smaller than the maximum supported number
+@item the pimpl idiom: the Callback class is passed around by
+value and delegates the crux of the work to its pimpl pointer.
+@item two pimpl implementations which derive from CallbackImpl
+FunctorCallbackImpl can be used with any functor-type
+while MemPtrCallbackImpl can be used with pointers to
+member functions.
+@item a reference list implementation to implement the Callback's
+value semantics.
+@end itemize
+
+This code most notably departs from the Alexandrescu
+implementation in that it does not use type lists to specify
+and pass around the types of the callback arguments.
+Of course, it also does not use copy-destruction semantics
+and relies on a reference list rather than autoPtr to hold
+the pointer.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/manual/figures/README Sun Jun 15 21:38:13 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.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/manual/figures/buffer.dia Sun Jun 15 21:38:13 2008 -0700
@@ -0,0 +1,1623 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<dia:diagram xmlns:dia="http://www.lysator.liu.se/~alla/dia/">
+ <dia:diagramdata>
+ <dia:attribute name="background">
+ <dia:color val="#ffffff"/>
+ </dia:attribute>
+ <dia:attribute name="pagebreak">
+ <dia:color val="#000099"/>
+ </dia:attribute>
+ <dia:attribute name="paper">
+ <dia:composite type="paper">
+ <dia:attribute name="name">
+ <dia:string>#A4#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="tmargin">
+ <dia:real val="2.8222000598907471"/>
+ </dia:attribute>
+ <dia:attribute name="bmargin">
+ <dia:real val="2.8222000598907471"/>
+ </dia:attribute>
+ <dia:attribute name="lmargin">
+ <dia:real val="2.8222000598907471"/>
+ </dia:attribute>
+ <dia:attribute name="rmargin">
+ <dia:real val="2.8222000598907471"/>
+ </dia:attribute>
+ <dia:attribute name="is_portrait">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="scaling">
+ <dia:real val="1"/>
+ </dia:attribute>
+ <dia:attribute name="fitto">
+ <dia:boolean val="false"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ <dia:attribute name="grid">
+ <dia:composite type="grid">
+ <dia:attribute name="width_x">
+ <dia:real val="1"/>
+ </dia:attribute>
+ <dia:attribute name="width_y">
+ <dia:real val="1"/>
+ </dia:attribute>
+ <dia:attribute name="visible_x">
+ <dia:int val="1"/>
+ </dia:attribute>
+ <dia:attribute name="visible_y">
+ <dia:int val="1"/>
+ </dia:attribute>
+ <dia:composite type="color"/>
+ </dia:composite>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#d8e5e5"/>
+ </dia:attribute>
+ <dia:attribute name="guides">
+ <dia:composite type="guides">
+ <dia:attribute name="hguides"/>
+ <dia:attribute name="vguides"/>
+ </dia:composite>
+ </dia:attribute>
+ </dia:diagramdata>
+ <dia:layer name="Background" visible="true">
+ <dia:object type="Flowchart - Box" version="0" id="O0">
+ <dia:attribute name="obj_pos">
+ <dia:point val="5,-17"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="4.95,-17.05;8.05,-14.95"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="5,-17"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="3"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.10000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#Count#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="6.5,-15.75"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="1"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Flowchart - Box" version="0" id="O1">
+ <dia:attribute name="obj_pos">
+ <dia:point val="8,-17"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="7.95,-17.05;11.05,-14.95"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="8,-17"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="3"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.10000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#Size#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="9.5,-15.75"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="1"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Flowchart - Box" version="0" id="O2">
+ <dia:attribute name="obj_pos">
+ <dia:point val="10.825,-17"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="10.775,-17.05;15.225,-14.95"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="10.825,-17"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="4.3499999999999996"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.10000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#Initial Start#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="13,-15.75"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="1"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Flowchart - Box" version="0" id="O3">
+ <dia:attribute name="obj_pos">
+ <dia:point val="15,-17"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="14.95,-17.05;19.05,-14.95"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="15,-17"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="4"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.10000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#Dirty Start#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="17,-15.75"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="1"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Flowchart - Box" version="0" id="O4">
+ <dia:attribute name="obj_pos">
+ <dia:point val="22.925,-17"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="22.875,-17.05;29.1,-14.95"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="22.925,-17"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="6.1249999999999964"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2"/>
+ </dia:attribute>
+ <dia:attribute name="inner_color">
+ <dia:color val="#90ee90"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.10000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#Unused Area#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="25.9875,-15.75"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="1"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Flowchart - Box" version="0" id="O5">
+ <dia:attribute name="obj_pos">
+ <dia:point val="19,-17"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="18.95,-17.05;23.05,-14.95"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="19,-17"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="4"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.10000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#Dirty Size#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="21,-15.75"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="1"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Standard - BezierLine" version="0" id="O6">
+ <dia:attribute name="obj_pos">
+ <dia:point val="17,-15"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="16.93,-15.3378;29.4316,-14.6622"/>
+ </dia:attribute>
+ <dia:attribute name="bez_points">
+ <dia:point val="17,-15"/>
+ <dia:point val="20,-11"/>
+ <dia:point val="26.0375,-11"/>
+ <dia:point val="29,-15"/>
+ </dia:attribute>
+ <dia:attribute name="corner_types">
+ <dia:enum val="0"/>
+ <dia:enum val="0"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow">
+ <dia:enum val="22"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_length">
+ <dia:real val="0.5"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_width">
+ <dia:real val="0.5"/>
+ </dia:attribute>
+ <dia:connections>
+ <dia:connection handle="0" to="O3" connection="13"/>
+ <dia:connection handle="3" to="O9" connection="11"/>
+ </dia:connections>
+ </dia:object>
+ <dia:object type="Standard - BezierLine" version="0" id="O7">
+ <dia:attribute name="obj_pos">
+ <dia:point val="21,-15"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="20.93,-15.3378;42.4316,-14.6622"/>
+ </dia:attribute>
+ <dia:attribute name="bez_points">
+ <dia:point val="21,-15"/>
+ <dia:point val="24,-11"/>
+ <dia:point val="39.0375,-11"/>
+ <dia:point val="42,-15"/>
+ </dia:attribute>
+ <dia:attribute name="corner_types">
+ <dia:enum val="0"/>
+ <dia:enum val="0"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow">
+ <dia:enum val="22"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_length">
+ <dia:real val="0.5"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_width">
+ <dia:real val="0.5"/>
+ </dia:attribute>
+ <dia:connections>
+ <dia:connection handle="0" to="O5" connection="13"/>
+ <dia:connection handle="3" to="O9" connection="15"/>
+ </dia:connections>
+ </dia:object>
+ <dia:object type="Standard - BezierLine" version="0" id="O8">
+ <dia:attribute name="obj_pos">
+ <dia:point val="9.5,-15"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="9.4309,-15.4359;48.4563,-9.59687"/>
+ </dia:attribute>
+ <dia:attribute name="bez_points">
+ <dia:point val="9.5,-15"/>
+ <dia:point val="23.5,-6"/>
+ <dia:point val="41.125,-10"/>
+ <dia:point val="48.125,-15"/>
+ </dia:attribute>
+ <dia:attribute name="corner_types">
+ <dia:enum val="0"/>
+ <dia:enum val="0"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow">
+ <dia:enum val="22"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_length">
+ <dia:real val="0.5"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_width">
+ <dia:real val="0.5"/>
+ </dia:attribute>
+ <dia:connections>
+ <dia:connection handle="0" to="O1" connection="13"/>
+ <dia:connection handle="3" to="O14" connection="15"/>
+ </dia:connections>
+ </dia:object>
+ <dia:object type="Flowchart - Box" version="0" id="O9">
+ <dia:attribute name="obj_pos">
+ <dia:point val="29,-17"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="28.95,-17.05;42.05,-14.95"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="29,-17"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="13"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2"/>
+ </dia:attribute>
+ <dia:attribute name="inner_color">
+ <dia:color val="#a52a2a"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.10000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#Dirty Area#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="35.5,-15.75"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="1"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Standard - BezierLine" version="0" id="O10">
+ <dia:attribute name="obj_pos">
+ <dia:point val="13,-15"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="12.9296,-15.34;40.43,-11.1632"/>
+ </dia:attribute>
+ <dia:attribute name="bez_points">
+ <dia:point val="13,-15"/>
+ <dia:point val="18,-9"/>
+ <dia:point val="37,-11"/>
+ <dia:point val="40,-15"/>
+ </dia:attribute>
+ <dia:attribute name="corner_types">
+ <dia:enum val="0"/>
+ <dia:enum val="0"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow">
+ <dia:enum val="22"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_length">
+ <dia:real val="0.5"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_width">
+ <dia:real val="0.5"/>
+ </dia:attribute>
+ <dia:connections>
+ <dia:connection handle="0" to="O2" connection="13"/>
+ </dia:connections>
+ </dia:object>
+ <dia:object type="Standard - Line" version="0" id="O11">
+ <dia:attribute name="obj_pos">
+ <dia:point val="40,-22"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="30.9298,-29.0702;40.0702,-21.9298"/>
+ </dia:attribute>
+ <dia:attribute name="conn_endpoints">
+ <dia:point val="40,-22"/>
+ <dia:point val="31,-29"/>
+ </dia:attribute>
+ <dia:attribute name="numcp">
+ <dia:int val="1"/>
+ </dia:attribute>
+ <dia:connections>
+ <dia:connection handle="1" to="O13" connection="11"/>
+ </dia:connections>
+ </dia:object>
+ <dia:object type="Standard - Line" version="0" id="O12">
+ <dia:attribute name="obj_pos">
+ <dia:point val="40,-22"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="39.9293,-29.0707;47.0707,-21.9293"/>
+ </dia:attribute>
+ <dia:attribute name="conn_endpoints">
+ <dia:point val="40,-22"/>
+ <dia:point val="47,-29"/>
+ </dia:attribute>
+ <dia:attribute name="numcp">
+ <dia:int val="1"/>
+ </dia:attribute>
+ <dia:connections>
+ <dia:connection handle="1" to="O13" connection="15"/>
+ </dia:connections>
+ </dia:object>
+ <dia:object type="Flowchart - Box" version="0" id="O13">
+ <dia:attribute name="obj_pos">
+ <dia:point val="31,-31"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="30.95,-31.05;47.05,-28.95"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="31,-31"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="16"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.10000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#Virtual Zero Area#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="39,-29.75"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="1"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Flowchart - Box" version="0" id="O14">
+ <dia:attribute name="obj_pos">
+ <dia:point val="42,-17"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="41.95,-17.05;48.175,-14.95"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="42,-17"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="6.1249999999999964"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2"/>
+ </dia:attribute>
+ <dia:attribute name="inner_color">
+ <dia:color val="#90ee90"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.10000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#Unused Area#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="45.0625,-15.75"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="1"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:group>
+ <dia:object type="Flowchart - Box" version="0" id="O15">
+ <dia:attribute name="obj_pos">
+ <dia:point val="5,-31"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="4.95,-31.05;9.05,-28.95"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="5,-31"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="4"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.10000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#Data#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="7,-29.75"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="1"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Flowchart - Box" version="0" id="O16">
+ <dia:attribute name="obj_pos">
+ <dia:point val="9,-31"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="8.95,-31.05;15.15,-28.95"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="9,-31"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="6.1000000000000014"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.10000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#Zero Area Size#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="12.05,-29.75"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="1"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Flowchart - Box" version="0" id="O17">
+ <dia:attribute name="obj_pos">
+ <dia:point val="15,-31"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="14.95,-31.05;21.05,-28.95"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="15,-31"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="6"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.10000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#Used start#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="18,-29.75"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="1"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Flowchart - Box" version="0" id="O18">
+ <dia:attribute name="obj_pos">
+ <dia:point val="21,-31"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="20.95,-31.05;26.05,-28.95"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="21,-31"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="5"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.10000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#Used Size#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="23.5,-29.75"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="1"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ </dia:group>
+ <dia:group>
+ <dia:object type="Flowchart - Box" version="0" id="O19">
+ <dia:attribute name="obj_pos">
+ <dia:point val="5,-2"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="4.95,-2.05;9.05,0.05"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="5,-2"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="4"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.10000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#Data#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="7,-0.75"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="1"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Flowchart - Box" version="0" id="O20">
+ <dia:attribute name="obj_pos">
+ <dia:point val="9,-2"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="8.95,-2.05;15.15,0.05"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="9,-2"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="6.1000000000000014"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.10000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#Zero Area Size#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="12.05,-0.75"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="1"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Flowchart - Box" version="0" id="O21">
+ <dia:attribute name="obj_pos">
+ <dia:point val="15,-2"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="14.95,-2.05;21.05,0.05"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="15,-2"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="6"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.10000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#Used start#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="18,-0.75"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="1"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Flowchart - Box" version="0" id="O22">
+ <dia:attribute name="obj_pos">
+ <dia:point val="21,-2"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="20.95,-2.05;26.05,0.05"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="21,-2"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="5"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.10000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#Used Size#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="23.5,-0.75"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="1"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ </dia:group>
+ <dia:object type="Standard - Line" version="0" id="O23">
+ <dia:attribute name="obj_pos">
+ <dia:point val="7,-2"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="4.49821,-15.1254;7.05702,-1.94298"/>
+ </dia:attribute>
+ <dia:attribute name="conn_endpoints">
+ <dia:point val="7,-2"/>
+ <dia:point val="5,-15"/>
+ </dia:attribute>
+ <dia:attribute name="numcp">
+ <dia:int val="1"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow">
+ <dia:enum val="22"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_length">
+ <dia:real val="0.5"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_width">
+ <dia:real val="0.5"/>
+ </dia:attribute>
+ <dia:connections>
+ <dia:connection handle="0" to="O19" connection="2"/>
+ <dia:connection handle="1" to="O0" connection="11"/>
+ </dia:connections>
+ </dia:object>
+ <dia:object type="Standard - Line" version="0" id="O24">
+ <dia:attribute name="obj_pos">
+ <dia:point val="7,-29"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="4.49858,-29.0575;7.05754,-16.8685"/>
+ </dia:attribute>
+ <dia:attribute name="conn_endpoints">
+ <dia:point val="7,-29"/>
+ <dia:point val="5,-17"/>
+ </dia:attribute>
+ <dia:attribute name="numcp">
+ <dia:int val="1"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow">
+ <dia:enum val="22"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_length">
+ <dia:real val="0.5"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_width">
+ <dia:real val="0.5"/>
+ </dia:attribute>
+ <dia:connections>
+ <dia:connection handle="0" to="O15" connection="13"/>
+ <dia:connection handle="1" to="O0" connection="0"/>
+ </dia:connections>
+ </dia:object>
+ <dia:object type="Standard - BezierLine" version="0" id="O25">
+ <dia:attribute name="obj_pos">
+ <dia:point val="12.05,-31"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="11.9915,-34.0955;39.3889,-30.6111"/>
+ </dia:attribute>
+ <dia:attribute name="bez_points">
+ <dia:point val="12.05,-31"/>
+ <dia:point val="13,-36"/>
+ <dia:point val="36,-34"/>
+ <dia:point val="39,-31"/>
+ </dia:attribute>
+ <dia:attribute name="corner_types">
+ <dia:enum val="0"/>
+ <dia:enum val="0"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow">
+ <dia:enum val="22"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_length">
+ <dia:real val="0.5"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_width">
+ <dia:real val="0.5"/>
+ </dia:attribute>
+ <dia:connections>
+ <dia:connection handle="0" to="O16" connection="2"/>
+ <dia:connection handle="3" to="O13" connection="2"/>
+ </dia:connections>
+ </dia:object>
+ <dia:object type="Standard - BezierLine" version="0" id="O26">
+ <dia:attribute name="obj_pos">
+ <dia:point val="18,-29"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="17.9318,-29.0682;33.2055,-21.5098"/>
+ </dia:attribute>
+ <dia:attribute name="bez_points">
+ <dia:point val="18,-29"/>
+ <dia:point val="22,-22"/>
+ <dia:point val="30,-23"/>
+ <dia:point val="33,-22"/>
+ </dia:attribute>
+ <dia:attribute name="corner_types">
+ <dia:enum val="0"/>
+ <dia:enum val="0"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow">
+ <dia:enum val="22"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_length">
+ <dia:real val="0.5"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_width">
+ <dia:real val="0.5"/>
+ </dia:attribute>
+ <dia:connections>
+ <dia:connection handle="0" to="O17" connection="13"/>
+ <dia:connection handle="3" to="O28" connection="0"/>
+ </dia:connections>
+ </dia:object>
+ <dia:object type="Standard - BezierLine" version="0" id="O27">
+ <dia:attribute name="obj_pos">
+ <dia:point val="24,-29"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="23.9293,-29.0707;41.5,-21.95"/>
+ </dia:attribute>
+ <dia:attribute name="bez_points">
+ <dia:point val="24,-29"/>
+ <dia:point val="28,-25"/>
+ <dia:point val="41,-27"/>
+ <dia:point val="41,-22"/>
+ </dia:attribute>
+ <dia:attribute name="corner_types">
+ <dia:enum val="0"/>
+ <dia:enum val="0"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow">
+ <dia:enum val="22"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_length">
+ <dia:real val="0.5"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_width">
+ <dia:real val="0.5"/>
+ </dia:attribute>
+ <dia:connections>
+ <dia:connection handle="3" to="O28" connection="4"/>
+ </dia:connections>
+ </dia:object>
+ <dia:object type="Flowchart - Box" version="0" id="O28">
+ <dia:attribute name="obj_pos">
+ <dia:point val="33,-22"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="32.95,-22.05;41.05,-19.95"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="33,-22"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="8"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2"/>
+ </dia:attribute>
+ <dia:attribute name="inner_color">
+ <dia:color val="#1e90ff"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.10000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#Used#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="37,-20.75"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="1"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Flowchart - Box" version="0" id="O29">
+ <dia:attribute name="obj_pos">
+ <dia:point val="35,-8"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="34.95,-8.05;42.05,-5.95"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="35,-8"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="7"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2"/>
+ </dia:attribute>
+ <dia:attribute name="inner_color">
+ <dia:color val="#1e90ff"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.10000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#Used#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="38.5,-6.75"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="1"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Standard - BezierLine" version="0" id="O30">
+ <dia:attribute name="obj_pos">
+ <dia:point val="12.05,0"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="11.9807,-0.294111;39.3576,4.18349"/>
+ </dia:attribute>
+ <dia:attribute name="bez_points">
+ <dia:point val="12.05,0"/>
+ <dia:point val="16,6"/>
+ <dia:point val="36,5"/>
+ <dia:point val="38.9,0"/>
+ </dia:attribute>
+ <dia:attribute name="corner_types">
+ <dia:enum val="0"/>
+ <dia:enum val="0"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow">
+ <dia:enum val="22"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_length">
+ <dia:real val="0.5"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_width">
+ <dia:real val="0.5"/>
+ </dia:attribute>
+ <dia:connections>
+ <dia:connection handle="0" to="O20" connection="13"/>
+ </dia:connections>
+ </dia:object>
+ <dia:object type="Standard - Line" version="0" id="O31">
+ <dia:attribute name="obj_pos">
+ <dia:point val="40,-6"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="32.9318,-6.06822;40.0682,-1.93178"/>
+ </dia:attribute>
+ <dia:attribute name="conn_endpoints">
+ <dia:point val="40,-6"/>
+ <dia:point val="33,-2"/>
+ </dia:attribute>
+ <dia:attribute name="numcp">
+ <dia:int val="1"/>
+ </dia:attribute>
+ <dia:connections>
+ <dia:connection handle="1" to="O33" connection="0"/>
+ </dia:connections>
+ </dia:object>
+ <dia:object type="Standard - Line" version="0" id="O32">
+ <dia:attribute name="obj_pos">
+ <dia:point val="40,-6"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="39.9329,-6.06708;42.0671,-1.93292"/>
+ </dia:attribute>
+ <dia:attribute name="conn_endpoints">
+ <dia:point val="40,-6"/>
+ <dia:point val="42,-2"/>
+ </dia:attribute>
+ <dia:attribute name="numcp">
+ <dia:int val="1"/>
+ </dia:attribute>
+ <dia:connections>
+ <dia:connection handle="1" to="O33" connection="4"/>
+ </dia:connections>
+ </dia:object>
+ <dia:object type="Flowchart - Box" version="0" id="O33">
+ <dia:attribute name="obj_pos">
+ <dia:point val="33,-2"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="32.95,-2.05;42.05,0.05"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="33,-2"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="9"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.10000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#Virtual Zero Area#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="37.5,-0.75"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="1"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Standard - BezierLine" version="0" id="O34">
+ <dia:attribute name="obj_pos">
+ <dia:point val="18,-2"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="17.9343,-7.50205;35.1202,-1.93435"/>
+ </dia:attribute>
+ <dia:attribute name="bez_points">
+ <dia:point val="18,-2"/>
+ <dia:point val="25,-5"/>
+ <dia:point val="28,-6"/>
+ <dia:point val="35,-7"/>
+ </dia:attribute>
+ <dia:attribute name="corner_types">
+ <dia:enum val="0"/>
+ <dia:enum val="0"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow">
+ <dia:enum val="22"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_length">
+ <dia:real val="0.5"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_width">
+ <dia:real val="0.5"/>
+ </dia:attribute>
+ <dia:connections>
+ <dia:connection handle="0" to="O21" connection="2"/>
+ <dia:connection handle="3" to="O29" connection="7"/>
+ </dia:connections>
+ </dia:object>
+ <dia:object type="Standard - BezierLine" version="0" id="O35">
+ <dia:attribute name="obj_pos">
+ <dia:point val="23.5,-2"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="23.4296,-8.86763;42.2683,-1.92958"/>
+ </dia:attribute>
+ <dia:attribute name="bez_points">
+ <dia:point val="23.5,-2"/>
+ <dia:point val="26,-5"/>
+ <dia:point val="36,-11"/>
+ <dia:point val="42,-8"/>
+ </dia:attribute>
+ <dia:attribute name="corner_types">
+ <dia:enum val="0"/>
+ <dia:enum val="0"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow">
+ <dia:enum val="22"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_length">
+ <dia:real val="0.5"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_width">
+ <dia:real val="0.5"/>
+ </dia:attribute>
+ <dia:connections>
+ <dia:connection handle="0" to="O22" connection="2"/>
+ <dia:connection handle="3" to="O29" connection="4"/>
+ </dia:connections>
+ </dia:object>
+ <dia:object type="Standard - Line" version="0" id="O36">
+ <dia:attribute name="obj_pos">
+ <dia:point val="33,-20"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="32.95,-20.05;33.05,-16.95"/>
+ </dia:attribute>
+ <dia:attribute name="conn_endpoints">
+ <dia:point val="33,-20"/>
+ <dia:point val="33,-17"/>
+ </dia:attribute>
+ <dia:attribute name="numcp">
+ <dia:int val="1"/>
+ </dia:attribute>
+ <dia:attribute name="line_style">
+ <dia:enum val="4"/>
+ </dia:attribute>
+ <dia:connections>
+ <dia:connection handle="0" to="O28" connection="11"/>
+ </dia:connections>
+ </dia:object>
+ <dia:object type="Standard - Line" version="0" id="O37">
+ <dia:attribute name="obj_pos">
+ <dia:point val="41,-20"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="40.95,-20.05;41.05,-16.95"/>
+ </dia:attribute>
+ <dia:attribute name="conn_endpoints">
+ <dia:point val="41,-20"/>
+ <dia:point val="41,-17"/>
+ </dia:attribute>
+ <dia:attribute name="numcp">
+ <dia:int val="1"/>
+ </dia:attribute>
+ <dia:attribute name="line_style">
+ <dia:enum val="4"/>
+ </dia:attribute>
+ <dia:connections>
+ <dia:connection handle="0" to="O28" connection="15"/>
+ </dia:connections>
+ </dia:object>
+ <dia:object type="Standard - Line" version="0" id="O38">
+ <dia:attribute name="obj_pos">
+ <dia:point val="35,-15"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="34.95,-15.05;35.05,-7.95"/>
+ </dia:attribute>
+ <dia:attribute name="conn_endpoints">
+ <dia:point val="35,-15"/>
+ <dia:point val="35,-8"/>
+ </dia:attribute>
+ <dia:attribute name="numcp">
+ <dia:int val="1"/>
+ </dia:attribute>
+ <dia:attribute name="line_style">
+ <dia:enum val="4"/>
+ </dia:attribute>
+ <dia:connections>
+ <dia:connection handle="1" to="O29" connection="0"/>
+ </dia:connections>
+ </dia:object>
+ <dia:object type="Standard - Line" version="0" id="O39">
+ <dia:attribute name="obj_pos">
+ <dia:point val="40,-22"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="39.95,-22.05;40.05,-5.95"/>
+ </dia:attribute>
+ <dia:attribute name="conn_endpoints">
+ <dia:point val="40,-22"/>
+ <dia:point val="40,-6"/>
+ </dia:attribute>
+ <dia:attribute name="numcp">
+ <dia:int val="1"/>
+ </dia:attribute>
+ <dia:attribute name="line_style">
+ <dia:enum val="4"/>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Standard - Line" version="0" id="O40">
+ <dia:attribute name="obj_pos">
+ <dia:point val="42,-15"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="41.95,-15.05;42.05,-7.95"/>
+ </dia:attribute>
+ <dia:attribute name="conn_endpoints">
+ <dia:point val="42,-15"/>
+ <dia:point val="42,-8"/>
+ </dia:attribute>
+ <dia:attribute name="numcp">
+ <dia:int val="1"/>
+ </dia:attribute>
+ <dia:attribute name="line_style">
+ <dia:enum val="4"/>
+ </dia:attribute>
+ <dia:connections>
+ <dia:connection handle="0" to="O9" connection="15"/>
+ <dia:connection handle="1" to="O29" connection="4"/>
+ </dia:connections>
+ </dia:object>
+ <dia:object type="Standard - Text" version="1" id="O41">
+ <dia:attribute name="obj_pos">
+ <dia:point val="5,1"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="5,0.175;7.125,1.55"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#Buffer#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="5,1"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="0"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ <dia:attribute name="valign">
+ <dia:enum val="3"/>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Standard - Text" version="1" id="O42">
+ <dia:attribute name="obj_pos">
+ <dia:point val="6,-14"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="6,-14.825;9.825,-13.45"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#BufferData#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="6,-14"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="0"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ <dia:attribute name="valign">
+ <dia:enum val="3"/>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Standard - Text" version="1" id="O43">
+ <dia:attribute name="obj_pos">
+ <dia:point val="5,-32"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="5,-32.825;7.125,-31.45"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#Buffer#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="5,-32"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="0"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ <dia:attribute name="valign">
+ <dia:enum val="3"/>
+ </dia:attribute>
+ </dia:object>
+ </dia:layer>
+</dia:diagram>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/manual/figures/packet.obj Sun Jun 15 21:38:13 2008 -0700
@@ -0,0 +1,227 @@
+%TGIF 4.1.43-QPL
+state(0,37,100.000,0,64,0,32,0,9,1,1,1,0,0,0,1,0,'Courier-Bold',1,103680,0,3,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,'').
+box('black','',32,48,240,256,0,3,1,0,0,0,0,0,0,'3',0,[
+]).
+text('black',64,10,1,0,1,121,28,3,22,6,0,0,0,0,2,121,28,0,0,"",0,0,0,0,32,'',[
+minilines(121,28,0,0,0,0,0,[
+mini_line(121,22,6,0,0,0,[
+str_block(0,121,22,6,0,0,0,0,0,[
+str_seg('black','Times-Roman',0,138240,121,22,6,0,0,0,0,0,0,0,
+ "class Packet")])
+])
+])]).
+text('black',416,100,1,0,1,116,28,15,22,6,0,0,0,0,2,116,28,0,0,"",0,0,0,0,122,'',[
+minilines(116,28,0,0,0,0,0,[
+mini_line(116,22,6,0,0,0,[
+str_block(0,116,22,6,0,0,0,0,0,[
+str_seg('black','Times-Roman',0,138240,116,22,6,0,0,0,0,0,0,0,
+ "class Buffer")])
+])
+])]).
+text('black',48,178,4,0,1,83,69,32,14,4,0,0,0,0,2,83,69,0,0,"",0,0,0,0,192,'',[
+minilines(83,69,0,0,0,0,0,[
+mini_line(80,14,4,0,0,0,[
+str_block(0,80,14,4,0,-1,0,0,0,[
+str_seg('black','Times-Bold',1,80640,80,14,4,0,-1,0,0,0,0,0,
+ "private data:")])
+]),
+mini_line(59,14,3,0,0,0,[
+str_block(0,59,14,3,0,0,0,0,0,[
+str_seg('black','Times-Roman',0,80640,59,14,3,0,0,0,0,0,0,0,
+ "- unique id")])
+]),
+mini_line(83,14,3,0,0,0,[
+str_block(0,83,14,3,0,0,0,0,0,[
+str_seg('black','Times-Roman',0,80640,83,14,3,0,0,0,0,0,0,0,
+ "- Buffer object")])
+]),
+mini_line(76,14,3,0,0,0,[
+str_block(0,76,14,3,0,0,0,0,0,[
+str_seg('black','Times-Roman',0,80640,76,14,3,0,0,0,0,0,0,0,
+ "- Tags object")])
+])
+])]).
+text('black',112,288,1,0,1,103,28,82,22,6,0,0,0,0,2,103,28,0,0,"",0,0,0,0,310,'',[
+minilines(103,28,0,0,0,0,0,[
+mini_line(103,22,6,0,0,0,[
+str_block(0,103,22,6,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,138240,103,22,6,0,-1,0,0,0,0,0,
+ "class Tags")])
+])
+])]).
+text('black',48,50,5,0,1,175,86,176,14,4,0,0,0,0,2,175,86,0,0,"",0,0,0,0,64,'',[
+minilines(175,86,0,0,0,0,0,[
+mini_line(105,14,4,0,0,0,[
+str_block(0,105,14,4,0,-1,0,0,0,[
+str_seg('black','Times-Bold',1,80640,105,14,4,0,-1,0,0,0,0,0,
+ "public functions:")])
+]),
+mini_line(80,14,3,0,0,0,[
+str_block(0,80,14,3,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,80640,80,14,3,0,-1,0,0,0,0,0,
+ "- constructors")])
+]),
+mini_line(175,14,3,0,0,0,[
+str_block(0,175,14,3,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,80640,175,14,3,0,-1,0,0,0,0,0,
+ "- add/remove/peek at Headers")])
+]),
+mini_line(155,14,3,0,0,0,[
+str_block(0,155,14,3,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,80640,155,14,3,0,-1,0,0,0,0,0,
+ "- add/remove/peek at Tags")])
+]),
+mini_line(88,14,3,0,0,0,[
+str_block(0,88,14,3,0,0,0,0,0,[
+str_seg('black','Times-Roman',0,80640,88,14,3,0,0,0,0,0,0,0,
+ "- fragmentation")])
+])
+])]).
+box('black','',384,144,614,352,0,3,1,245,0,0,0,0,0,'3',0,[
+]).
+text('black',400,274,4,0,1,204,69,246,14,4,0,0,0,0,2,204,69,0,0,"",0,0,0,0,288,'',[
+minilines(204,69,0,0,0,0,0,[
+mini_line(80,14,4,0,0,0,[
+str_block(0,80,14,4,0,-1,0,0,0,[
+str_seg('black','Times-Bold',1,80640,80,14,4,0,-1,0,0,0,0,0,
+ "private data:")])
+]),
+mini_line(193,14,3,0,0,0,[
+str_block(0,193,14,3,0,0,0,0,0,[
+str_seg('black','Times-Roman',0,80640,193,14,3,0,0,0,0,0,0,0,
+ "- struct BufferData, a dynamically")])
+]),
+mini_line(160,14,3,0,0,0,[
+str_block(0,160,14,3,0,0,0,0,0,[
+str_seg('black','Times-Roman',0,80640,160,14,3,0,0,0,0,0,0,0,
+ "varying byte buffer to which")])
+]),
+mini_line(204,14,3,0,0,0,[
+str_block(0,204,14,3,0,0,0,0,0,[
+str_seg('black','Times-Roman',0,80640,204,14,3,0,0,0,0,0,0,0,
+ "data can be prepended or appended")])
+])
+])]).
+text('black',400,146,5,0,1,188,86,247,14,4,0,0,0,0,2,188,86,0,0,"",0,0,0,0,160,'',[
+minilines(188,86,0,0,0,0,0,[
+mini_line(105,14,4,0,0,0,[
+str_block(0,105,14,4,0,-1,0,0,0,[
+str_seg('black','Times-Bold',1,80640,105,14,4,0,-1,0,0,0,0,0,
+ "public functions:")])
+]),
+mini_line(172,14,3,0,0,0,[
+str_block(0,172,14,3,0,0,0,0,0,[
+str_seg('black','Times-Roman',0,80640,172,14,3,0,0,0,0,0,0,0,
+ "- Iterators to move byte buffer")])
+]),
+mini_line(171,14,3,0,0,0,[
+str_block(0,171,14,3,0,0,0,0,0,[
+str_seg('black','Times-Roman',0,80640,171,14,3,0,0,0,0,0,0,0,
+ "pointers forward or backward")])
+]),
+mini_line(188,14,3,0,0,0,[
+str_block(0,188,14,3,0,0,0,0,0,[
+str_seg('black','Times-Roman',0,80640,188,14,3,0,0,0,0,0,0,0,
+ "- functions to read and write data")])
+]),
+mini_line(132,14,3,0,0,0,[
+str_block(0,132,14,3,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,80640,132,14,3,0,-1,0,0,0,0,0,
+ "of various sized chunks")])
+])
+])]).
+box('black','',96,324,304,532,0,3,1,264,0,0,0,0,0,'3',0,[
+]).
+text('black',112,454,4,0,1,167,69,265,14,4,0,0,0,0,2,167,69,0,0,"",0,0,0,0,468,'',[
+minilines(167,69,0,0,0,0,0,[
+mini_line(80,14,4,0,0,0,[
+str_block(0,80,14,4,0,-1,0,0,0,[
+str_seg('black','Times-Bold',1,80640,80,14,4,0,-1,0,0,0,0,0,
+ "private data:")])
+]),
+mini_line(167,14,3,0,0,0,[
+str_block(0,167,14,3,0,0,0,0,0,[
+str_seg('black','Times-Roman',0,80640,167,14,3,0,0,0,0,0,0,0,
+ "- singly linked-list of TagData")])
+]),
+mini_line(158,14,3,0,0,0,[
+str_block(0,158,14,3,0,0,0,0,0,[
+str_seg('black','Times-Roman',0,80640,158,14,3,0,0,0,0,0,0,0,
+ "structures, with a reference")])
+]),
+mini_line(32,14,3,0,0,0,[
+str_block(0,32,14,3,0,0,0,0,0,[
+str_seg('black','Times-Roman',0,80640,32,14,3,0,0,0,0,0,0,0,
+ "count")])
+])
+])]).
+text('black',112,326,5,0,1,155,86,266,14,4,0,0,0,0,2,155,86,0,0,"",0,0,0,0,340,'',[
+minilines(155,86,0,0,0,0,0,[
+mini_line(105,14,4,0,0,0,[
+str_block(0,105,14,4,0,-1,0,0,0,[
+str_seg('black','Times-Bold',1,80640,105,14,4,0,-1,0,0,0,0,0,
+ "public functions:")])
+]),
+mini_line(80,14,3,0,0,0,[
+str_block(0,80,14,3,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,80640,80,14,3,0,-1,0,0,0,0,0,
+ "- constructors")])
+]),
+mini_line(155,14,3,0,0,0,[
+str_block(0,155,14,3,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,80640,155,14,3,0,-1,0,0,0,0,0,
+ "- templates to add, remove,")])
+]),
+mini_line(148,14,3,0,0,0,[
+str_block(0,148,14,3,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,80640,148,14,3,0,-1,0,0,0,0,0,
+ "or peek at Tags of various")])
+]),
+mini_line(31,14,3,0,0,0,[
+str_block(0,31,14,3,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,80640,31,14,3,0,-1,0,0,0,0,0,
+ "types")])
+])
+])]).
+poly('black','',2,[
+ 59,245,96,320],0,2,1,272,0,0,3,0,0,0,0,'2',0,0,
+ "0","",[
+ 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
+]).
+poly('black','',2,[
+ 123,246,288,320],0,2,1,280,0,0,3,0,0,0,0,'2',0,0,
+ "0","",[
+ 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
+]).
+poly('black','',2,[
+ 141,219,379,147],0,2,1,286,0,0,3,0,0,0,0,'2',0,0,
+ "0","",[
+ 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
+]).
+poly('black','',2,[
+ 132,226,375,335],0,2,1,287,0,0,3,0,0,0,0,'2',0,0,
+ "0","",[
+ 0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
+]).
Binary file doc/manual/figures/sockets-overview.dia has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/manual/log.texi Sun Jun 15 21:38:13 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/manual/manual.css Sun Jun 15 21:38:13 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/manual/manual.texi Sun Jun 15 21:38:13 2008 -0700
@@ -0,0 +1,97 @@
+\input texinfo @c -*-texinfo-*-
+@c %**start of header
+@setfilename ns-3.info
+@settitle ns-3 manual
+@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 @uref{http://www.nsnam.org/tutorial/index.html,,ns-3 Tutorial}
+@item Reference Manual (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} manual.
+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 Manual (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 Reference Manual
+@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 Manual (html version)
+
+For a pdf version of this manual,
+see @uref{http://www.nsnam.org/docs/manual.pdf}.
+
+@insertcopying
+@end ifnottex
+
+@menu
+* ns-3 Packets::
+* ns-3 Callbacks::
+* Sockets APIs::
+* ns-3 routing overview::
+* Troubleshooting
+@end menu
+
+@include packets.texi
+@include callbacks.texi
+@include sockets.texi
+@c @include output.texi
+@include routing.texi
+@c @include other.texi
+@include troubleshoot.texi
+
+@printindex cp
+
+@bye
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/manual/other.texi Sun Jun 15 21:38:13 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/manual/output.texi Sun Jun 15 21:38:13 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/manual/packets.texi Sun Jun 15 21:38:13 2008 -0700
@@ -0,0 +1,620 @@
+@node ns-3 Packets
+@chapter ns-3 Packets
+
+The design of the Packet framework of @emph{ns} was heavily guided by a few
+important use-cases:
+@itemize @bullet
+@item avoid changing the core of the simulator to introduce
+new types of packet headers or trailers
+@item maximize the ease of integration with real-world code
+and systems
+@item make it easy to support fragmentation, defragmentation,
+and, concatenation which are important, especially in wireless systems.
+@item make memory management of this object efficient
+@item allow actual application data or dummy application bytes for
+emulated applications
+@end itemize
+
+@emph{ns} Packet objects contain a buffer of bytes: protocol headers and
+trailers are serialized in this buffer of bytes using user-provided
+serialization and deserialization routines. The content of this byte
+buffer is expected to match bit-for-bit the content of a real packet on
+a real network implementing the protocol of interest.
+
+Fragmentation and defragmentation are quite natural to implement within
+this context: since we have a buffer of real bytes, we can split it in
+multiple fragments and re-assemble these fragments. We expect that this
+choice will make it really easy to wrap our Packet data structure within
+Linux-style skb or BSD-style mbuf to integrate real-world kernel code in
+the simulator. We also expect that performing a real-time plug of the
+simulator to a real-world network will be easy.
+
+Because we understand that simulation developers often wish to store in
+packet objects data which is not found in the real packets (such as
+timestamps or any kind of similar in-band data), the @emph{ns} Packet class
+can also store extra per-packet "Tags" which are 16 bytes blobs of data.
+Any Packet can store any number of unique Tags, each of which is
+uniquely identified by its C++ type. These tags make it easy to attach
+per-model data to a packet without having to patch the main Packet
+class or Packet facilities.
+
+Memory management of Packet objects is entirely automatic and extremely
+efficient: memory for the application-level payload can be modelized by
+a virtual buffer of zero-filled bytes for which memory is never allocated
+unless explicitely requested by the user or unless the packet is fragmented.
+Furthermore, copying, adding, and, removing headers or trailers to a packet
+has been optimized to be virtually free through a technique known as
+Copy On Write.
+
+Packets (messages) are fundamental objects in the simulator and
+their design is important from a performance and resource management
+perspective. There
+are various ways to design the simulation packet, and tradeoffs
+among the different approaches. In particular, there is a
+tension between ease-of-use, performance, and safe interface
+design.
+
+There are a few requirements on this object design:
+@itemize @bullet
+@item Creation, management, and deletion of this object
+should be as simple as possible, while avoiding the
+chance for memory leaks and/or heap corruption;
+@item Packets should support serialization and deserialization
+so that network emulation is supported;
+@item Packets should support fragmentation and concatenation
+(multiple packets in a data link frame), especially for wireless
+support;
+@item It should be natural for packets to carry actual application
+data, or if there is only an emulated application and there is
+no need to carry dummy bytes, smaller packets could be used with
+just the headers and a record of the payload size, but not actual
+application bytes, conveyed in the simulated packet.
+@item Packets should facilitate BSD-like operations on mbufs, for
+support of ported operating system stacks.
+@item Additional side-information should be supported, such as
+a tag for cross-layer information.
+@end itemize
+
+@section Packet design overview
+
+Unlike @emph{ns-2}, in which Packet objects contain a buffer of C++
+structures corresponding to protocol headers, each network packet in
+@emph{ns-3} contains a byte Buffer and a list of Tags:
+@itemize @bullet
+@item The byte buffer stores the serialized content of the chunks
+added to a packet. The serialized representation of these chunks is
+expected to match that of real network packets bit for bit
+(although nothing forces you to do this) which means that the content
+of a packet buffer is expected to be that of a real packet.
+Packets can also be created with an arbitrary zero-filled payload
+for which no real memory is allocated.
+@item The list of tags stores an arbitrarily large set of arbitrary
+user-provided data structures in the packet. Each Tag is uniquely
+identified by its type; only one instance of each
+type of data structure is allowed in a list of tags. These tags typically
+contain per-packet cross-layer information or flow identifiers (i.e.,
+things that you wouldn't find in the bits on the wire). Each tag
+stored in the tag list can be at most 16 bytes.
+Trying to attach bigger data structures will trigger
+crashes at runtime. The 16 byte limit is a modifiable compilation
+constant.
+@end itemize
+
+@float Figure,fig:packets
+@caption{Implementation overview of Packet class.}
+@image{figures/packet}
+@end float
+
+Figure @ref{fig:packets} is a high-level overview of the Packet
+implementation; more detail on the byte Buffer implementation
+is provided later in Figure @ref{fig:buffer}.
+In \nsthree, the Packet byte buffer is analogous to a Linux skbuff
+or BSD mbuf; it is a serialized representation of the actual
+data in the packet. The tag list is a container for extra
+items useful for simulation convenience; if a Packet is converted
+to an emulated packet and put over an actual network, the tags
+are stripped off and the byte buffer is copied directly
+into a real packet.
+
+The Packet class has value semantics: it can be freely copied around,
+allocated on the stack, and passed to functions as arguments. Whenever
+an instance is copied, the full underlying data is not copied; it
+has ``copy-on-write'' (COW) semantics. Packet instances can be passed
+by value to function arguments without any performance hit.
+
+The fundamental classes for adding to and removing from the byte
+buffer are @code{class Header} and @code{class Trailer}.
+Headers are more common but the below discussion also largely applies to
+protocols using trailers. Every protocol header that needs to
+be inserted and removed from a Packet instance should derive from
+the abstract Header base class and implement the private pure
+virtual methods listed below:
+@itemize @bullet
+@item @code{ns3::Header::SerializeTo()}
+@item @code{ns3::Header::DeserializeFrom()}
+@item @code{ns3::Header::GetSerializedSize()}
+@item @code{ns3::Header::PrintTo()}
+@end itemize
+Basically, the first three functions are used to serialize and deserialize
+protocol control information to/from a Buffer. For example,
+one may define @code{class TCPHeader : public Header}. The
+TCPHeader object will typically consist of some private data
+(like a sequence number) and public interface access functions
+(such as checking the bounds of an input). But the underlying
+representation of the TCPHeader in a Packet Buffer is 20 serialized
+bytes (plus TCP options). The TCPHeader::SerializeTo() function would
+therefore be designed to write these 20 bytes properly into
+the packet, in network byte order. The last function is used
+to define how the Header object prints itself onto an output stream.
+
+Similarly, user-defined Tags can be appended to the packet.
+Unlike Headers, Tags are not serialized into a contiguous buffer
+but are stored in an array. By default, Tags are limited to 16 bytes in
+size. Tags can be flexibly defined to be any type, but there
+can only be one instance of any particular object type in
+the Tags buffer at any time. The implementation makes use
+of templates to generate the proper set of Add(), Remove(),
+and Peek() functions for each Tag type.
+
+@section Packet interface
+
+The public member functions of a Packet object are as follows:
+
+@subsection Constructors
+@verbatim
+ /**
+ * Create an empty packet with a new uid (as returned
+ * by getUid).
+ */
+ Packet ();
+ /**
+ * Create a packet with a zero-filled payload.
+ * The memory necessary for the payload is not allocated:
+ * it will be allocated at any later point if you attempt
+ * to fragment this packet or to access the zero-filled
+ * bytes. The packet is allocated with a new uid (as
+ * returned by getUid).
+ *
+ * \param size the size of the zero-filled payload
+ */
+ Packet (uint32_t size);
+@end verbatim
+
+@subsection Adding and removing Buffer data
+The below code is reproduced for Header class only; similar functions
+exist for Trailers.
+@verbatim
+ /**
+ * Add header to this packet. This method invokes the
+ * ns3::Header::serializeTo method to request the header to serialize
+ * itself in the packet buffer.
+ *
+ * \param header a reference to the header to add to this packet.
+ */
+ void Add (Header const &header);
+ /**
+ * Deserialize header from this packet. This method invokes the
+ * ns3::Header::deserializeFrom method to request the header to deserialize
+ * itself from the packet buffer. This method does not remove
+ * the data from the buffer. It merely reads it.
+ *
+ * \param header a reference to the header to deserialize from the buffer
+ */
+ void Peek (Header &header);
+ /**
+ * Remove a deserialized header from the internal buffer.
+ * This method removes the bytes read by Packet::peek from
+ * the packet buffer.
+ *
+ * \param header a reference to the header to remove from the internal buffer.
+ */
+ void Remove (Header const &header);
+ /**
+ * Add trailer to this packet. This method invokes the
+ * ns3::Trailer::serializeTo method to request the trailer to serialize
+ * itself in the packet buffer.
+ *
+ * \param trailer a reference to the trailer to add to this packet.
+ */
+@end verbatim
+
+@subsection Adding and removing Tags
+@verbatim
+ /**
+ * Attach a tag to this packet. The tag is fully copied
+ * in a packet-specific internal buffer. This operation
+ * is expected to be really fast.
+ *
+ * \param tag a pointer to the tag to attach to this packet.
+ */
+ template <typename T>
+ void AddTag (T const &tag);
+ /**
+ * Remove a tag from this packet. The data stored internally
+ * for this tag is copied in the input tag if an instance
+ * of this tag type is present in the internal buffer. If this
+ * tag type is not present, the input tag is not modified.
+ *
+ * This operation can be potentially slow and might trigger
+ * unexpectedly large memory allocations. It is thus
+ * usually a better idea to create a copy of this packet,
+ * and invoke removeAllTags on the copy to remove all
+ * tags rather than remove the tags one by one from a packet.
+ *
+ * \param tag a pointer to the tag to remove from this packet
+ * \returns true if an instance of this tag type is stored
+ * in this packet, false otherwise.
+ */
+ template <typename T>
+ bool RemoveTag (T &tag);
+ /**
+ * Copy a tag stored internally to the input tag. If no instance
+ * of this tag is present internally, the input tag is not modified.
+ *
+ * \param tag a pointer to the tag to read from this packet
+ * \returns true if an instance of this tag type is stored
+ * in this packet, false otherwise.
+ */
+ template <typename T>
+ bool PeekTag (T &tag) const;
+ /**
+ * Remove all the tags stored in this packet. This operation is
+ * much much faster than invoking removeTag n times.
+ */
+ void RemoveAllTags (void);
+@end verbatim
+
+@subsection Fragmentation
+@verbatim
+ /**
+ * Create a new packet which contains a fragment of the original
+ * packet. The returned packet shares the same uid as this packet.
+ *
+ * \param start offset from start of packet to start of fragment to create
+ * \param length length of fragment to create
+ * \returns a fragment of the original packet
+ */
+ Packet CreateFragment (uint32_t start, uint32_t length) const;
+
+ /**
+ * Concatenate the input packet at the end of the current
+ * packet. This does not alter the uid of either packet.
+ *
+ * \param packet packet to concatenate
+ */
+ void addAtEnd (Packet packet);
+
+ /oncatenate the input packet at the end of the current
+ * packet. This does not alter the uid of either packet.
+ *
+ * \param packet packet to concatenate
+ */
+ void AddAtEnd (Packet packet);
+ /**
+ * Concatenate the fragment of the input packet identified
+ * by the offset and size parameters at the end of the current
+ * packet. This does not alter the uid of either packet.
+ *
+ * \param packet to concatenate
+ * \param offset offset of fragment to copy from the start of the input packet
+ * \param size size of fragment of input packet to copy.
+ */
+ void AddAtEnd (Packet packet, uint32_t offset, uint32_t size);
+ /**
+ * Remove size bytes from the end of the current packet
+ * It is safe to remove more bytes that what is present in
+ * the packet.
+ *
+ * \param size number of bytes from remove
+ */
+ void RemoveAtEnd (uint32_t size);
+ /**
+ * Remove size bytes from the start of the current packet.
+ * It is safe to remove more bytes that what is present in
+ * the packet.
+ *
+ * \param size number of bytes from remove
+ */
+ void RemoveAtStart (uint32_t size);
+@end verbatim
+
+@subsection Miscellaneous
+@verbatim
+ /**
+ * \returns the size in bytes of the packet (including the zero-filled
+ * initial payload)
+ */
+ uint32_t GetSize (void) const;
+ /**
+ * If you try to change the content of the buffer
+ * returned by this method, you will die.
+ *
+ * \returns a pointer to the internal buffer of the packet.
+ */
+ uint8_t const *PeekData (void) const;
+ /**
+ * A packet is allocated a new uid when it is created
+ * empty or with zero-filled payload.
+ *
+ * \returns an integer identifier which uniquely
+ * identifies this packet.
+ */
+ uint32_t GetUid (void) const;
+@end verbatim
+
+@section Using Headers
+@emph{walk through an example of adding a UDP header}
+
+@section Using Tags
+@emph{walk through an example of adding a flow ID}
+
+@section Using Fragmentation
+@emph{walk through an example of link-layer fragmentation/reassembly}
+
+@section Sample program
+The below sample program (from @code{ns3/samples/main-packet.cc}) illustrates
+some use of the Packet, Header, and Tag classes.
+
+@verbatim
+/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */
+#include "ns3/packet.h"
+#include "ns3/header.h"
+#include <iostream>
+
+using namespace ns3;
+
+/* A sample Header implementation
+ */
+class MyHeader : public Header {
+public:
+ MyHeader ();
+ virtual ~MyHeader ();
+
+ void SetData (uint16_t data);
+ uint16_t GetData (void) const;
+private:
+ virtual void PrintTo (std::ostream &os) const;
+ virtual void SerializeTo (Buffer::Iterator start) const;
+ virtual void DeserializeFrom (Buffer::Iterator start);
+ virtual uint32_t GetSerializedSize (void) const;
+
+ uint16_t m_data;
+};
+
+MyHeader::MyHeader ()
+{}
+MyHeader::~MyHeader ()
+{}
+void
+MyHeader::PrintTo (std::ostream &os) const
+{
+ os << "MyHeader data=" << m_data << std::endl;
+}
+uint32_t
+MyHeader::GetSerializedSize (void) const
+{
+ return 2;
+}
+void
+MyHeader::SerializeTo (Buffer::Iterator start) const
+{
+ // serialize in head of buffer
+ start.WriteHtonU16 (m_data);
+}
+void
+MyHeader::DeserializeFrom (Buffer::Iterator start)
+{
+ // deserialize from head of buffer
+ m_data = start.ReadNtohU16 ();
+}
+
+void
+MyHeader::SetData (uint16_t data)
+{
+ m_data = data;
+}
+uint16_t
+MyHeader::GetData (void) const
+{
+ return m_data;
+}
+
+/* A sample Tag implementation
+ */
+struct MyTag {
+ uint16_t m_streamId;
+};
+
+static TagRegistration<struct MyTag> g_MyTagRegistration ("ns3::MyTag", 0);
+
+
+static void
+Receive (Packet p)
+{
+ MyHeader my;
+ p.Peek (my);
+ p.Remove (my);
+ std::cout << "received data=" << my.GetData () << std::endl;
+ struct MyTag myTag;
+ p.PeekTag (myTag);
+}
+
+
+int main (int argc, char *argv[])
+{
+ Packet p;
+ MyHeader my;
+ my.SetData (2);
+ std::cout << "send data=2" << std::endl;
+ p.Add (my);
+ struct MyTag myTag;
+ myTag.m_streamId = 5;
+ p.AddTag (myTag);
+ Receive (p);
+ return 0;
+}
+@end verbatim
+
+@section Implementation details
+
+@subsection Private member variables
+
+A Packet object's interface provides access to some private
+data:
+@verbatim
+ Buffer m_buffer;
+ Tags m_tags;
+ uint32_t m_uid;
+ static uint32_t m_global_uid;
+@end verbatim
+Each Packet has a Buffer and a Tags object, and a 32-bit unique ID (m\_uid).
+A static member variable keeps track of the UIDs allocated. Note
+that real network packets do not have a UID; the UID is therefore an
+instance of data that normally would be stored as a Tag in the packet.
+However, it was felt that a UID is a special case that is so often
+used in simulations that it would be more convenient to store it
+in a member variable.
+
+@subsection Buffer implementation
+
+Class Buffer represents a buffer of bytes. Its size is
+automatically adjusted to hold any data prepended
+or appended by the user. Its implementation is optimized
+to ensure that the number of buffer resizes is minimized,
+by creating new Buffers of the maximum size ever used.
+The correct maximum size is learned at runtime during use by
+recording the maximum size of each packet.
+
+Authors of new Header or Trailer classes need to know the public
+API of the Buffer class. (add summary here)
+
+The byte buffer is implemented as follows:
+@verbatim
+ struct BufferData {
+ uint32_t m_count;
+ uint32_t m_size;
+ uint32_t m_initialStart;
+ uint32_t m_dirtyStart;
+ uint32_t m_dirtySize;
+ uint8_t m_data[1];
+ };
+ struct BufferData *m_data;
+ uint32_t m_zeroAreaSize;
+ uint32_t m_start;
+ uint32_t m_size;
+@end verbatim
+
+@itemize @bullet
+@item @code{BufferData::m_count}: reference count for BufferData structure
+@item @code{BufferData::m_size}: size of data buffer stored in BufferData structure
+@item @code{BufferData::m_initialStart}: offset from start of data buffer where data was first inserted
+@item @code{BufferData::m_dirtyStart}: offset from start of buffer where every Buffer which holds a reference to this BufferData instance have written data so far
+@item @code{BufferData::m_dirtySize}: size of area where data has been written so far
+@item @code{BufferData::m_data}: pointer to data buffer
+@item @code{Buffer::m_zeroAreaSize}: size of zero area which extends before @code{m_initialStart}
+@item @code{Buffer::m_start}: offset from start of buffer to area used by this buffer
+@item @code{Buffer::m_size}: size of area used by this Buffer in its BufferData structure
+@end itemize
+
+@float Figure,fig:buffer
+@caption{Implementation overview of a packet's byte Buffer.}
+@image{figures/buffer,15cm}
+@end float
+
+This data structure is summarized in Figure @ref{fig:buffer}.
+Each Buffer holds a pointer to an instance of a BufferData. Most
+Buffers should be able to share the same underlying BufferData and
+thus simply increase the BufferData's reference count. If they have to
+change the content of a BufferData inside the Dirty Area, and if the
+reference count is not one, they first create a copy of the BufferData and
+then complete their state-changing operation.
+
+@subsection Tags implementation
+Tags are implemented by a single pointer which points to the start of a
+linked list ofTagData data structures. Each TagData structure points
+to the next TagData in the list (its next pointer contains zero to
+indicate the end of the linked list). Each TagData contains an integer
+unique id which identifies the type of the tag stored in the TagData.
+@verbatim
+struct TagData {
+ struct TagData *m_next;
+ uint32_t m_id;
+ uint32_t m_count;
+ uint8_t m_data[Tags::SIZE];
+};
+class Tags {
+ struct TagData *m_next;
+};
+@end verbatim
+
+Adding a tag is a matter of inserting a new TagData at the head of
+the linked list. Looking at a tag requires you to find the relevant
+TagData in the linked list and copy its data into the user data
+structure. Removing a tag and updating the content of a tag
+requires a deep copy of the linked list before performing this operation.
+On the other hand, copying a Packet and its tags is a matter of
+copying the TagData head pointer and incrementing its reference count.
+
+Tags are found by the unique mapping betweent the Tag type and
+its underlying id. This is why at most one instance of any Tag
+can be stored in a packet. The mapping between Tag type and
+underlying id is performed by a registration as follows:
+@verbatim
+/* A sample Tag implementation
+ */
+struct MyTag {
+ uint16_t m_streamId;
+};
+@end verbatim
+
+@emph{add description of TagRegistration for printing}
+
+@subsection Memory management
+
+@emph{Describe free list.}
+
+@emph{Describe dataless vs. data-full packets.}
+
+@subsection Copy-on-write semantics
+The current implementation of the byte buffers and tag list is based
+on COW (Copy On Write). An introduction to COW can be found in Scott
+Meyer's "More Effective C++", items 17 and 29). This design feature
+and aspects of the public interface borrows from the packet design
+of the Georgia Tech Network Simulator.
+This implementation of COW uses a customized reference counting
+smart pointer class.
+
+What COW means is that
+copying packets without modifying them is very cheap (in terms of CPU
+and memory usage) and modifying them can be also very cheap. What is
+key for proper COW implementations is being
+able to detect when a given modification of the state of a packet triggers
+a full copy of the data prior to the modification: COW systems need
+to detect when an operation is ``dirty'' and must therefore invoke
+a true copy.
+
+Dirty operations:
+@itemize @bullet
+@item Packet::RemoveTag()
+@item Packet::Add()
+@item both versions of ns3::Packet::AddAtEnd()
+@end itemize
+
+Non-dirty operations:
+@itemize @bullet
+@item Packet::AddTag()
+@item Packet::RemoveAllTags()
+@item Packet::PeekTag()
+@item Packet::Peek()
+@item Packet::Remove()
+@item Packet::CreateFragment()
+@item Packet::RemoveAtStart()
+@item Packet::RemoveAtEnd()
+@end itemize
+
+Dirty operations will always be slower than non-dirty operations,
+sometimes by several orders of magnitude. However, even the
+dirty operations have been optimized for common use-cases which
+means that most of the time, these operations will not trigger
+data copies and will thus be still very fast.
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/manual/routing.texi Sun Jun 15 21:38:13 2008 -0700
@@ -0,0 +1,373 @@
+@node ns-3 routing overview
+@chapter ns-3 routing overview
+
+This chapter describes the overall design of routing in the
+@code{src/internet-stack}
+module, and some details about the routing approachs currently
+implemented.
+
+@node Routing-Overview
+@section Overview
+
+We intend to support traditional routing approaches and protocols,
+ports of open source routing implementations, and facilitate research
+into unorthodox routing techniques.
+For simulations that are not primarily focused on routing and that
+simply want correct routing tables to occur somehow, we have an
+global centralized routing capability. A singleton object
+(GlobalRouteManager) be instantiated, builds a network map, and
+populates a forwarding table on each node at time t=0 in the
+simulation. Simulation script writers can use the same node
+API to manually enter routes as well.
+
+@node Support for multiple routing protocols
+@section Support for multiple routing protocols
+
+Typically, multiple routing protocols are supported in user space and
+coordinate to write a single forwarding table in the kernel. Presently
+in @command{ns-3}, the implementation instead allows for multiple routing
+protocols to build/keep their own routing state, and the IPv4 implementation
+will query each one of these routing protocols (in some order determined
+by the simulation author) until a route is found.
+
+We chose this approach because it may better
+faciliate the integration of disparate routing approaches that may
+be difficult to coordinate the writing to a single table, approaches
+where more information than destination IP address (e.g., source
+routing) is used to determine the next hop, and on-demand
+routing approaches where packets must be cached.
+
+There are presently two routing protocols defined:
+@itemize @bullet
+@item class Ipv4StaticRouting (covering both unicast and multicast)
+@item Optimized Link State Routing (a MANET protocol defined in
+@uref{http://www.ietf.org/rfc/rfc3626.txt,,RFC 3626})
+@end itemize
+but first we describe how multiple routing protocols are supported.
+
+@subsection class Ipv4RoutingProtocol
+
+@code{class Ipv4RoutingProtocol} derives from ns-3 Object which means
+that it supports interface aggregation and reference counting. Routing
+protocols should inherit from this class, defined in src/node/ipv4.cc.
+
+The main function that must be supported by these protocols is called
+@code{RequestRoute}.
+@verbatim
+ * This method is called whenever a node's IPv4 forwarding engine
+ * needs to lookup a route for a given packet and IP header.
+ *
+ * The routing protocol implementation may determine immediately it
+ * should not be handling this particular the route request. For
+ * instance, a routing protocol may decline to search for routes for
+ * certain classes of addresses, like link-local. In this case,
+ * RequestRoute() should return false and the routeReply callback
+ * must not be invoked.
+ *
+ * If the routing protocol implementations assumes it can provide
+ * the requested route, then it should return true, and the
+ * routeReply callback must be invoked, either immediately before
+ * returning true (synchronously), or in the future (asynchronous).
+ * The routing protocol may use any information available in the IP
+ * header and packet as routing key, although most routing protocols
+ * use only the destination address (as given by
+ * ipHeader.GetDestination ()). The routing protocol is also
+ * allowed to add a new header to the packet, which will appear
+ * immediately after the IP header, although most routing do not
+ * insert any extra header.
+ */
+ virtual bool RequestRoute (uint32_t ifIndex,
+ const Ipv4Header &ipHeader,
+ Ptr<Packet> packet,
+ RouteReplyCallback routeReply) = 0;
+@end verbatim
+
+This class also provides a typedef (used above) for a special Callback
+that will pass to the callback function the Ipv4Route that is found (see the
+Doxygen documentation):
+@verbatim
+ typedef Callback<void, bool, const Ipv4Route&, Ptr<Packet>, const Ipv4Header&> RouteReplyCallback;
+@end verbatim
+
+@subsection Ipv4::AddRoutingProtocol
+
+Class Ipv4 provides a pure virtual function declaration for the
+method that allows one to add a routing protocol:
+@verbatim
+ void AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol,
+ int16_t priority);
+@end verbatim
+This method is implemented by class Ipv4L3Protocol in the internet-stack
+module.
+
+The priority variable above governs the priority in which the routing
+protocols are inserted. Notice that it is a signed int.
+When the class Ipv4L3Protocol is instantiated, a single routing
+protocol (Ipv4StaticRouting, introduced below) is added at priority
+zero. Internally, a list of Ipv4RoutingProtocols is stored, and
+and the routing protocols are each consulted in decreasing order
+of priority to see whether a match is found. Therefore, if you
+want your Ipv4RoutingProtocol to have priority lower than the static
+routing, insert it with priority less than 0; e.g.:
+@verbatim
+ m_ipv4->AddRoutingProtocol (m_routingTable, -10);
+@end verbatim
+
+@subsection Ipv4L3Protocol::Lookup
+
+The main function for obtaining a route is shown below:
+@verbatim
+Ipv4L3Protocol::Lookup (
+ uint32_t ifIndex,
+ Ipv4Header const &ipHeader,
+ Ptr<Packet> packet,
+ Ipv4RoutingProtocol::RouteReplyCallback routeReply)
+@end verbatim
+
+This function will search the list of routing protocols, in priority order,
+until a route is found. It will then invoke the RouteReplyCallback
+and no further routing protocols will be searched. If the caller does
+not want to constrain the possible interface, it can be wildcarded
+as such:
+@verbatim
+ Lookup (Ipv4RoutingProtocol::IF_INDEX_ANY, ipHeader, packet, routeReply);
+@end verbatim
+
+@node Roadmap and Future work
+@section Roadmap and Future work
+
+Some goals for future support are:
+
+Users should be able to trace (either debug print, or redirect to a trace
+file) the routing table in a format such as used in an
+Unix implementation:
+@verbatim
+# netstat -nr (or # route -n)
+Kernel IP routing table
+Destination Gateway Genmask Flags MSS Window irtt Iface
+127.0.0.1 * 255.255.255.255 UH 0 0 0 lo
+172.16.1.0 * 255.255.255.0 U 0 0 0 eth0
+172.16.2.0 172.16.1.1 255.255.255.0 UG 0 0 0 eth0
+
+# ip route show
+192.168.99.0/24 dev eth0 scope link
+127.0.0.0/8 dev lo scope link
+default via 192.168.99.254 dev eth0
+@end verbatim
+
+Global computation of multicast routing should be implemented as well.
+This would ignore group membership and ensure that a copy of every
+sourced multicast datagram would be delivered to each node.
+This might be implemented as an RPF mechanism that functioned on-demand
+by querying the forwarding table,
+and perhaps optimized by a small multicast forwarding cache. It is
+a bit trickier to implement over wireless links where the input
+interface is the same as the output interface; other aspects of the
+packet must be considered and the forwarding logic slightly changed
+to allow for forwarding out the same interface.
+
+In the future, work on bringing XORP or quagga routing to ns, but it will
+take several months to port and enable.
+
+There are presently no roadmap plans for IPv6.
+
+@node Static routing
+@section Static routing
+
+The internet-stack module provides one routing protocol (Ipv4StaticRouting)
+by default. This routing protocol allows one to add unicast or multicast
+static routes to a node.
+
+@node Unicast routing
+@section Unicast routing
+
+The unicast static routing API may be accessed via the functions
+@verbatim
+void Ipv4::AddHostRouteTo ()
+void Ipv4::AddNetworkRouteTo ()
+void Ipv4::SetDefaultRoute ()
+uint32_t Ipv4::GetNRoutes ()
+Ipv4Route Ipv4::GetRoute ()
+@end verbatim
+
+@uref{http://www.nsnam.org/doxygen/index.html,,Doxygen} documentation
+provides full documentation of these methods. These methods are forwarding
+functions to the actual implementation in Ipv4StaticRouting, when using
+the internet-stack module.
+
+@node Multicast routing
+@section Multicast routing
+
+The following function is used to add a static multicast route
+to a node:
+@verbatim
+void
+Ipv4StaticRouting::AddMulticastRoute (Ipv4Address origin,
+ Ipv4Address group,
+ uint32_t inputInterface,
+ std::vector<uint32_t> outputInterfaces);
+@end verbatim
+
+A multicast route must specify an origin IP address, a multicast group and
+an input network interface index as conditions and provide a vector of
+output network interface indices over which packets matching the conditions
+are sent.
+
+Typically there are two main types of multicast routes: routes of the
+first kind are used during forwarding. All of the conditions must be
+exlicitly provided. The second kind of routes are used to get packets off
+of a local node. The difference is in the input interface. Routes for
+forwarding will always have an explicit input interface specified. Routes
+off of a node will always set the input interface to a wildcard specified
+by the index Ipv4RoutingProtocol::IF\_INDEX\_ANY.
+
+For routes off of a local node wildcards may be used in the origin and
+multicast group addresses. The wildcard used for Ipv4Adresses is that
+address returned by Ipv4Address::GetAny () -- typically "0.0.0.0". Usage
+of a wildcard allows one to specify default behavior to varying degrees.
+
+For example, making the origin address a wildcard, but leaving the
+multicast group specific allows one (in the case of a node with multiple
+interfaces) to create different routes using different output interfaces
+for each multicast group.
+
+If the origin and multicast addresses are made wildcards, you have created
+essentially a default multicast address that can forward to multiple
+interfaces. Compare this to the actual default multicast address that is
+limited to specifying a single output interface for compatibility with
+existing functionality in other systems.
+
+Another command sets the default multicast route:
+@verbatim
+void
+Ipv4StaticRouting::SetDefaultMulticastRoute (uint32_t outputInterface);
+@end verbatim
+
+This is the multicast equivalent of the unicast version SetDefaultRoute.
+We tell the routing system what to do in the case where a specific route
+to a destination multicast group is not found. The system forwards
+packets out the specified interface in the hope that "something out there"
+knows better how to route the packet. This method is only used in
+initially sending packets off of a host. The default multicast route is
+not consulted during forwarding -- exact routes must be specified using
+AddMulticastRoute for that case.
+
+Since we're basically sending packets to some entity we think may know
+better what to do, we don't pay attention to "subtleties" like origin
+address, nor do we worry about forwarding out multiple interfaces. If the
+default multicast route is set, it is returned as the selected route from
+LookupStatic irrespective of origin or multicast group if another specific
+route is not found.
+
+Finally, a number of additional functions are provided to fetch and
+remove multicast routes:
+@verbatim
+ uint32_t GetNMulticastRoutes (void) const;
+
+ Ipv4MulticastRoute *GetMulticastRoute (uint32_t i) const;
+
+ Ipv4MulticastRoute *GetDefaultMulticastRoute (void) const;
+
+ bool RemoveMulticastRoute (Ipv4Address origin,
+ Ipv4Address group,
+ uint32_t inputInterface);
+
+ void RemoveMulticastRoute (uint32_t index);
+@end verbatim
+
+@node Global centralized routing
+@section Global centralized routing
+
+Presently, global centralized IPv4 @emph{unicast} routing over both
+point-to-point and shared (CSMA) links is supported.
+The global centralized routing will be modified in the future to
+reduce computations once profiling finds the performance bottlenecks.
+
+@node Global Unicast Routing API
+@section Global Unicast Routing API
+
+The public API is very minimal. User scripts include the following:
+@verbatim
+#include "ns3/global-route-manager.h"
+@end verbatim
+
+After IP addresses are configured, the following function call will
+cause all of the nodes that have an Ipv4 interface to receive
+forwarding tables entered automatically by the GlobalRouteManager:
+@verbatim
+ GlobalRouteManager::PopulateRoutingTables ();
+@end verbatim
+
+@emph{Note:} A reminder that the wifi NetDevice is not yet supported
+(only CSMA and PointToPoint).
+
+@node Global Routing Implementation
+@section Global Routing Implementation
+
+A singleton object (GlobalRouteManager) is responsible for populating
+the static routes on each node, using the public Ipv4 API of that node.
+It queries each node in the topology for a "globalRouter" interface.
+If found, it uses the API of that interface to obtain a "link state
+advertisement (LSA)" for the router. Link State Advertisements
+are used in OSPF routing, and we follow their formatting.
+
+The GlobalRouteManager populates a link state database with LSAs
+gathered from the entire topology. Then, for each router in the topology,
+the GlobalRouteManager executes the OSPF shortest path first (SPF)
+computation on the database, and populates the routing tables on each
+node.
+
+The quagga (http://www.quagga.net) OSPF implementation was used as the
+basis for the routing computation logic.
+One benefit of following an existing OSPF SPF implementation is that
+OSPF already has defined link state advertisements for all common
+types of network links:
+@itemize @bullet
+@item point-to-point (serial links)
+@item point-to-multipoint (Frame Relay, ad hoc wireless)
+@item non-broadcast multiple access (ATM)
+@item broadcast (Ethernet)
+@end itemize
+Therefore, we think that enabling these other link types will be more
+straightforward now that the underlying OSPF SPF framework is in place.
+
+Presently, we can handle IPv4 point-to-point, numbered links, as well
+as shared broadcast (CSMA) links, and we do not do equal-cost multipath.
+
+The GlobalRouteManager first walks the list of nodes and aggregates
+a GlobalRouter interface to each one as follows:
+@verbatim
+ typedef std::vector < Ptr<Node> >::iterator Iterator;
+ for (Iterator i = NodeList::Begin (); i != NodeList::End (); i++)
+ {
+ Ptr<Node> node = *i;
+ Ptr<GlobalRouter> globalRouter = CreateObject<GlobalRouter> (node);
+ node->AggregateObject (globalRouter);
+ }
+@end verbatim
+
+This interface is later queried and used to generate a Link State
+Advertisement for each router, and this link state database is
+fed into the OSPF shortest path computation logic. The Ipv4 API
+is finally used to populate the routes themselves.
+
+@node Optimized Link State Routing (OLSR)
+@section Optimized Link State Routing (OLSR)
+
+This is the first dynamic routing protocol for @command{ns-3}. The implementation
+is found in the src/routing/olsr directory, and an example script is in
+examples/simple-point-to-point-olsr.cc.
+
+The following commands will enable OLSR in a simulation.
+
+@verbatim
+ olsr::EnableAllNodes (); // Start OLSR on all nodes
+ olsr::EnableNodes(InputIterator begin, InputIterator end); // Start on
+ // a list of nodes
+ olsr::EnableNode (Ptr<Node> node); // Start OLSR on "node" only
+@end verbatim
+
+Once instantiated, the agent can be started with the Start() command,
+and the OLSR "main interface" can be set with the SetMainInterface()
+command. A number of protocol constants are defined in olsr-agent-impl.cc.
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/manual/sockets.texi Sun Jun 15 21:38:13 2008 -0700
@@ -0,0 +1,243 @@
+@node Sockets APIs
+@chapter Sockets APIs
+
+The @uref{http://en.wikipedia.org/wiki/Berkeley_sockets,,sockets API}
+is a long-standing API used by user-space applications to access
+network services in the kernel. A ``socket'' is an abstraction, like
+a Unix file handle, that allows applications to connect to other
+Internet hosts and exchange reliable byte streams and unreliable
+datagrams, among other services.
+
+ns-3 provides two types of sockets APIs, and it is important to
+understand the differences between them. The first is a @emph{native}
+ns-3 API, while the second uses the services of the native API to
+provide a @uref{http://en.wikipedia.org/wiki/POSIX,,POSIX-like}
+API as part of an overall application process. Both APIs strive
+to be close to the typical sockets API that application writers
+on Unix systems are accustomed to, but the POSIX variant is much
+closer to a real system's sockets API.
+
+@section ns-3 sockets API
+
+The native sockets API for ns-3 provides an interface to various
+types of transport protocols (TCP, UDP) as well as to packet sockets
+and, in the future, Netlink-like sockets. However, users are cautioned
+to understand that the semantics are @strong{not} the exact same as
+one finds in a real system (for an API which is very much aligned
+to real systems, see the next section).
+
+@code{class ns3::Socket} is defined in @code{src/node/socket.cc,h}.
+Readers will note that many public member functions are aligned
+with real sockets function calls, and all other things being equal,
+we have tried to align with a Posix sockets API. However, note that:
+
+@itemize @bullet
+@item ns-3 applications handle a smart pointer to a Socket object, not
+a file descriptor;
+@item there is no notion of synchronous API or a ``blocking'' API;
+in fact, the model for interaction between application and socket is
+one of asynchronous I/O, which is not typically found in real systems
+(more on this below);
+@item the C-style socket address structures are not used;
+@item the API is not a complete sockets API, such as supporting
+all socket options or all function variants;
+@item many calls use @code{ns3::Packet} class to transfer data
+between application and socket. This may seem a little funny to
+people to pass ``Packets'' across a stream socket API, but think
+of these packets as just fancy byte buffers at this level (more
+on this also below).
+@end itemize
+
+@subsection Basic operation and calls
+
+@float Figure,fig:sockets-overview
+@caption{Implementation overview of native sockets API}
+@image{figures/sockets-overview, 10cm}
+@end float
+
+@subsubsection Creating sockets
+
+An application that wants to use sockets must first create one.
+On real systems, this is accomplished by calling socket():
+@verbatim
+ int
+ socket(int domain, int type, int protocol);
+@end verbatim
+which creates a socket in the system and returns an integer descriptor.
+
+In ns-3, we have no equivalent of a system call at the lower layers,
+so we adopt the following model. There are certain @emph{factory}
+objects that can create sockets. Each factory is capable of creating
+one type of socket, and if sockets of a particular type are able to
+be created on a given node, then a factory that can create such sockets
+must be aggregated to the Node.
+@verbatim
+ static Ptr<Socket> CreateSocket (Ptr<Node> node, TypeId tid);
+@end verbatim
+Examples of TypeIds to pass to this method are @code{TcpSocketFactory},
+@code{PacketSocketFactory}, and @code{UdpSocketFactory}.
+
+This method returns a smart pointer to a Socket object. Here is an
+example:
+@verbatim
+ Ptr<Node> n0;
+ // Do some stuff to build up the Node's internet stack
+ Ptr<Socket> localSocket = Socket::CreateSocket (n0, TcpSocketFactory::GetTypeId ());
+@end verbatim
+
+In some ns-3 code, sockets will not be explicitly created by user's
+main programs, if an ns-3 application does it. For instance, for
+@code{class ns3::OnOffApplication}, the function @code{StartApplication()}
+performs the socket creation, and the application holds the socket
+pointer.
+
+@subsubsection Using sockets
+
+Below is a typical sequence of socket calls for a TCP client in a
+real implementation:
+@itemize @bullet
+@item @code{sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);}
+@item @code{bind(sock, ...);}
+@item @code{connect(sock, ...);}
+@item @code{send(sock, ...);}
+@item @code{recv(sock, ...);}
+@item @code{close(sock);}
+@end itemize
+
+There are analogs to all of these calls in ns-3, but we will focus on
+two aspects here. First, most usage of sockets in real systems
+requires a way to manage I/O between the application and kernel.
+These models include @emph{blocking sockets}, @emph{signal-based I/O},
+and @emph{non-blocking sockets} with polling. In ns-3, we make use
+of the callback mechanisms to support a fourth mode, which is
+analogous to POSIX @emph{asynchronous I/O}.
+
+In this model, on the sending side, if the @code{send()} call were to
+fail because of insufficient buffers, the application suspends the
+sending of more data until a function registered at the
+@code{SetSendCallback()} callback is invoked. An application can
+also ask the socket how much space is available by calling
+@code{GetTxAvailable ()}. A typical sequence of events for
+sending data (ignoring connection setup) might be:
+
+@itemize @bullet
+@item @code{SetSendCallback (MakeCallback(&HandleSendCallback));}
+@item @code{Send ();}
+@item @code{Send ();}
+@item ...
+@item @code{// Send fails because buffer is full}
+@item (wait until HandleSendCallback() is called)
+@item (HandleSendCallback() is called by socket, since space now available)
+@item @code{Send (); // Start sending again}
+@end itemize
+
+Similarly, on the receive side, the socket user does not block on
+a call to @code{recv()}. Instead, the application sets a callback
+with @code{SetRecvCallback ()} in which the socket will notify the
+application when (and how much) there is data to be read, and
+the application then calls @code{Recv()} to read the data until
+no more can be read.
+
+@subsection Packet vs. buffer variants
+
+There are two basic variants of @code{Send()} and @code{Recv()} supported:
+@verbatim
+ virtual int Send (Ptr<Packet> p) = 0;
+ int Send (const uint8_t* buf, uint32_t size);
+
+ Ptr<Packet> Recv (void);
+ int Recv (uint8_t* buf, uint32_t size);
+@end verbatim
+
+The non-Packet variants are left for legacy API reasons. When calling
+the raw buffer variant of @code{Send()}, the buffer is immediately
+written into a Packet and the @code{Send (Ptr<Packet> p)} is invoked.
+
+Users may find it semantically odd to pass a Packet to a stream socket
+such as TCP. However, do not let the name bother you; think of
+@code{ns3::Packet} to be a fancy byte buffer. There are a few reasons why
+the Packet variants are more likely to be preferred in ns-3:
+
+@itemize @bullet
+@item Users can use the Tags facility of packets to, for example, encode
+a flow ID or other helper data.
+@item Users can exploit the copy-on-write implementation to avoid
+memory copies (on the receive side, the conversion back to a
+@code{uint8_t* buf} may sometimes incur an additional copy).
+@item Use of Packet is more aligned with the rest of the ns-3 API
+@end itemize
+
+@subsection Sending dummy data
+
+Sometimes, users want the simulator to just pretend that there is an
+actual data payload in the packet (e.g. to calculate transmission delay)
+but do not want to actually produce or consume the data. This is
+straightforward to support in ns-3; have applications call
+@code{Create<Packet> (size);} instead of @code{Create<Packet> (buffer, size);}.
+Similarly, passing in a zero to the pointer argument in the raw buffer
+variants has the same effect. Note that, if some subsequent code tries
+to read the Packet data buffer, the fake buffer will be converted to
+a real (zero'ed) buffer on the spot, and the efficiency will be lost there.
+
+@subsection Socket options
+
+@emph{to be completed}
+
+@subsection Socket errno
+
+@emph{to be completed}
+
+@subsection Example programs
+
+@emph{to be completed}
+
+@section POSIX-like sockets API
+
+@emph{this capability is under development and is scheduled for
+inclusion in August 2008 timeframe; see the repository
+http://code.nsnam.org/mathieu/ns-3-simu for details}
+
+The below is excerpted from Mathieu's post to ns-developers list
+on April 4, 2008.
+
+"To summarize, the goal is that the full posix/socket API is defined in
+src/process/simu.h: each posix type and function is re-defined there
+with a simu_ or SIMU_ prefix to avoid ugly name clashes and collisions
+(feel free to come up with a better prefix).
+
+Each process is created with a call to ProcessManager::Create and is
+attached to that ProcessManager instance. So, if the ProcessManager
+(which is aggregated to a Node in src/helper/process-helper.cc) is
+killed when the simulation ends, the system will automatically reclaim
+all the resources of each process associated to each manager. The same
+happens when an application "exits" from its main function.
+
+The example application defines two posix "processes": the function
+ClientProgram creates a udp socket on the localhost port 2000 and the
+function ServerProgram creates a udp socket on the localhost port 2000.
+The code does not work right now because I did not get the details of
+simu_read right yet but, I do plan to make this work at some point.
+
+I really think that this approach is worthwhile for many reasons, a few
+of which are outlined below:
+@itemize @bullet
+@item makes porting real world application code _much_ easier
+
+@item makes write applications for new users much easier because they can
+read the bsd socket api reference and documentation and write code
+directly.
+
+@item can be used to write applications which work in both simulation and
+in the real world at the same time. To do this, all you have to do is
+write your application to use the simu_ API, and, then, you can chose at
+compile-time which implementation of that API you want to use: you can
+pick one implementation which forwards all calls to the system BSD
+socket API or another one which forwards all calls to the attached
+ProcessManager. Arguably, I did not implement the version which forwards
+to system BSD sockets but, that should be pretty trivial.
+@end itemize
+
+So, anyway, comments about the overall API would be welcome. Students
+interested in the gsoc project for real-world code integration should
+consider looking at this also."
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/manual/statistics.texi Sun Jun 15 21:38:13 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/manual/troubleshoot.texi Sun Jun 15 21:38:13 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