A NS packet is composed of a stack of headers, and an optional data space (see Figure 12). As briefly mentioned in the "Simple Simulation Example" section, a packet header format is initialized when a Simulator object is created, where a stack of all registered (or possibly useable) headers, such as the common header that is commonly used by any objects as needed, IP header, TCP header, RTP header (UDP uses RTP header) and trace header, is defined, and the offset of each header in the stack is recorded. What this means is that whether or not a specific header is used, a stack composed of all registered headers is created when a packet is allocated by an agent, and a network object can access any header in the stack of a packet it processes using the corresponding offset value.
Usually, a packet only has the header stack (and a data space pointer
that is null). Although a packet can carry actual data (from an
application) by allocating a data space, very few application and
agent implementations support this. This is because it is meaningless
to carry data around in a non-real-time simulation. However, if you
want to implement an application that talks to another application
cross the network, you might want to use this feature with a little
modification in the underlying agent implementation. Another possible
approach would be creating a new header for the application and
modifying the underlying agent to write data received from the
application to the new header. The second approach is shown as an
example in a later section called "Add New Application and Agent".
Figure 12. NS Packet Format