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.

Figure 12. NS Packet Format

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".