An object of the PacketHeaderManager../ns-2/packet.h is used to manage the set of currently-active packet header types and assign each of them unique offsets in the BOB. It is defined in both the C++ and OTcl code:
{\rm From tcl/lib/ns-packet.tcl:} PacketHeaderManager set hdrlen_ 0 #XXX could potentially get rid of this by searching having a more # uniform offset concept... foreach pair { { Common off_cmn_ } { Mac off_mac_ } { LL off_ll_ } { Snoop off_snoop_ } { IP off_ip_ } { TCP off_tcp_ } { TCPA off_tcpasym_ } { Flags off_flags_ } { RTP off_rtp_ } { Message off_msg_ } { IVS off_ivs_ } { rtProtoDV off_DV_ } { CtrMcast off_CtrMcast_ } { Prune off_prune_ } { Tap off_tap_ } { aSRM off_asrm_ } { SRM off_srm_ }} { set cl [lindex $pair 0] set var [lindex $pair 1] PacketHeaderManager set vartab_($cl) $var } Simulator instproc create_packetformat { } { set pm [new PacketHeaderManager] foreach oclass [PacketHeader info subclass] { set L [split $oclass /] set cl [lindex $L 1] set var [PacketHeaderManager set vartab_($cl)] set off [$pm allochdr $cl] TclObject set $var $off } $self set packetManager_ $pm } PacketHeaderManager instproc allochdr cl { set size [PacketHeader/$cl set hdrlen_] $self instvar hdrlen_ set NS_ALIGN 8 # round up to nearest NS_ALIGN bytes set incr [expr ($size + ($NS_ALIGN-1)) & ~($NS_ALIGN-1)] set base $hdrlen_ incr hdrlen_ $incr return $base } {\rm From packet.cc:} /* manages active packet header types */ class PacketHeaderManager : public TclObject { public: PacketHeaderManager() { bind("hdrlen_", &Packet::hdrlen_); } };The code in tcl/lib/ns-packet.tcl is executed when the simulator initializes. Thus, the foreach statement is executed before the simulation begins, and initializes the OTcl class array vartab_ to contain the mapping between class the name and the name of the variable used to contain that class's header in a packet (which is initialized later). For example, the value of vartab_(IP) is set to off_ip_. Notice that here the off_hdrname_ stuff is only provided for backward compatibility reasons; as discussed above (11.1), packet headers should be accessed using hdr_hdrname::access().
The []create_packetformat instance procedure is part of the basic Simulator class and is called one time during simulator configuration. It first creates a single PacketHeaderManager object. The C++ constructor links the OTcl instance variable hdrlen_ (of class PacketHeaderManager) to the C++ variable Packet::hdrlen_ (a static member of the Packet class). This has the effect of setting Packet::hdrlen_ to zero. Note that binding across class types in this fashion is unusual.
After creating the packet manager, the foreach loop enables each of the packet headers of interest. This loop iterates through the list of defined packet headers of the form (hi, oi) where hi is the name of the ith header and oi is the name of the variable containing the location of the hi header in BOB. The placement of headers is performed by the allochdr instproc of the PacketHeaderManager OTcl class. The procedure keeps a running variable hdrlen_ with the current length of BOB as new packet headers are enabled. It also arranges for 8-byte alignment for any newly-enabled packet header. This is needed to ensure that when double-world length quantities are used in packet headers on machines where double-word alignment is required, access faults are not produced.11.3.