We will now show how it is possible to create a new dynamic packet type named MyPkt. Most of the setup (packet header, TCL stuff) is the same which has always been used for statically defined packet types in NS, the only significant change is the dynamic registration of the packet type. However, it is somehow confusing just to cover the differences... I'll just show you all the steps that are needed for this purpose.
First, create a mypacket.h
with the following content.
#ifndef MYPACKET_H #define MYPACKET_H #include<packet.h> extern packet_t PT_MYPKT; #define HDR_MYPKT(P) (hdr_mypkt::access(P)) typedef struct hdr_mypkt { // This members are always needed by NS static int offset_; inline static int& offset() { return offset_; } inline static struct hdr_mypkt* access(const Packet* p) { return (struct hdr_mypkt*)p->access(offset_); } // My custom header fields go here: int myseqno; double mytimestamp; } hdr_mypkt; #endif /* MYPACKET_H */
Basically, in the above file we define the structure of the header, provide the standard allocation/access methods for the simulator (i.e., hdr_mypkt::offset_
and hdr_mypkt::access()
), and declare the variable that will hold the dynamically registered packet type (PT_MYPKT
).
Now put the following in a file named mypacket.cc
:
#include"mypacket.h" packet_t PT_MYPKT; int hdr_mypkt::offset_; static class MyPktClass : public PacketHeaderClass { public: MyPktClass() : PacketHeaderClass("PacketHeader/MYPKT", sizeof(hdr_mypkt)) { this->bind(); bind_offset(&hdr_mypkt::offset_); PT_MYPKT = p_info::addPacket("MYPKT"); } } class_mypkt_hdr;
A first inportant thing to be noticed is that mypacket.cc
takes care of actually allocating the static variables PT_MYPKT
and hdr_mypkt::offset_
. The other important thing is the registration of the packet header within the simulator. It is to be noted that class_mypkt_hdr
is a static instance of MyPktClass
(and no other instance of this class will actually be used). Being static, class_mypkt_hdr
is created when the dynamic library we're building is loaded; at this time, the constructor of MyPktClass
will be called, which will accomplish the following tasks:
It is VERY IMPORTANT to remember that the memory for our header will NOT be allocated unless the following TCL code is executed:
PacketHeaderManager set tab_(PacketHeader/MYPKT) 1It is very convenient to put this instruction in a
EmbeddedTcl
code which is automatically executed when the library is loaded. For instance, in the example provided in the previous section, this code would have been put in the file foo-init.tcl
.
When all the above steps have been performed, it is possible to use the fields provided within hdr_mypkt
at simulation time.
Moreover, if we want at runtime to tag a packet as being of type MyPacket, all we need is to do the following:
hdr_cmn* ch = hdr_cmn::access(p); ch->ptype() = PT_MYPKT;