12.2.4 The PacketHeaderManager Class

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
        ......
        foreach prot {
                AODV
                ARP
                aSRM 
                Common 
                CtrMcast 
                Diffusion
                ......
                TORA
                UMP 
        } {
                add-packet-header $prot
        }
        Simulator instproc create_packetformat {} {
                PacketHeaderManager instvar tab_
                set pm [new PacketHeaderManager]
                foreach cl [PacketHeader info subclass] {
                        if [info exists tab_($cl)] {
                                set off [$pm allochdr $cl]
                                $cl offset $off
                        }
                }
                $self set packetManager_ $pm
        }
        PacketHeaderManager instproc allochdr cl {
                set size [$cl set hdrlen_]
                $self instvar hdrlen_
                set NS_ALIGN 8 # round up to nearest NS_ALIGN bytes, (needed on sparc/solaris);
                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 ~ns/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 tab_ to contain the mapping between class the name and the names of the currently active packet header classes. As discussed above (12.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 $(h_i, o_i)$ where $h_i$ is the name of the $i$th header and $o_i$ is the name of the variable containing the location of the $h_i$ 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.12.3.

Tom Henderson 2011-11-05