📄 packet_format.tex
字号:
%% personal commentary:% DRAFT DRAFT DRAFT% - KFALL%\chapter{Packet Headers and Formats}\label{chap:pformat}The procedures and functions described in this chapter can be found in\nsf{tcl/lib/ns-lib.tcl},\nsf{tcl/lib/ns-packet.tcl}, and \nsf{packet.\{cc, h\}}.Objects in the \clsref{Packet}{../ns-2/packets.h} are the fundamental unit ofexchange between objects in the simulation.The class \code{Packet}provides enough information to link a packet on to a list(\ie, in a \code{PacketQueue} or on a free list of packets),refer to a buffer containing packet headersthat are defined on a per-protocol basis,and to refer to a buffer of packet data.New protocols may define their own packet headers or may extendexisting headers with additional fields.New packet headers are introduced into the simulatorby defining a C++ structure with the needed fields,defining a static class to provide OTcl linkage,and then modifying some of the simulator initialization codeto assign a byte offset in each packet where the new headeris to be located relative to others.When the simulator is initialized through OTcl,a user may choose to enableonly a subset of the compiled-in packet formats, resulting ina modest savings of memory during the execution of the simulation.Presently, most configured-in packet formats are enabled.The management of which packet formats are currently enabledin a simulation is handled by a special packet header managerobject described below.This object supports an OTcl method used to specifywhich packet headers will be used in a simulation.If an object in the simulator makes use of a field in a headerwhich has not been enabled, a run-time fatal program abort occurs.\section{A Protocol-Specific Packet Header}\label{sec:ppackethdr}Protocol developerswill often wish to provide a specific header type to be used in packets.Doing so allows a new protocol implementationto avoid overloading already-existing header fields.We consider a simplified version of RTP as an example.The RTP header will require a sequence number fields and a sourceidentifier field.The following classes create the needed header(see \nsf{rtp.h} and \nsf{rtp.cc}):\begin{program}{\rm From rtp.h:} /* {\cf rtp packet. For now, just have srcid + seqno.} */ struct hdr_rtp \{ u_int32_t srcid_; int seqno_; /* {\cf per-field member functions } */ u_int32_t& srcid() \{ return (srcid_); \} int& seqno() \{ return (seqno_); \} \};{\rm From rtp.cc:} class RTPAgent: public Agent \{ \ldots int off_rtp_; \}; class RTPHeaderClass : public PacketHeaderClass \{ public: RTPHeaderClass() : PacketHeaderClass("PacketHeader/RTP", sizeof(hdr_rtp)) \{\} \} class_rtphdr; void RTPAgent::sendpkt() \{ Packet* p = allocpkt(); hdr_rtp *rh = (hdr_rtp*)p->access(off_rtp_); lastpkttime_ = Scheduler::instance().clock(); /* {\cf Fill in srcid_ and seqno} */ rh->seqno() = seqno_++; rh->srcid() = session_->srcid(); target_->recv(p, 0); \} RTPAgent::RTPAgent() : session_(0), lastpkttime_(-1e6) \{ type_ = PT_RTP; bind("seqno_", &seqno_); bind("off_rtp_", &off_rtp_); \}\end{program}The first structure defines the layout(in terms of words and their placement):which fields are needed and how big they are.This structure definition is only used by thecompiler to compute byte offsets of fields;no objects of this structure type are ever directly allocated.The structure also provides member functions which in turnprovide a layer of data hiding for objects wishing to reador modify header fields of packets.Note that the variable \code{off_rtp_} is usedto find the byte offset at which the rtp header is locatedin an arbitrary packet.To access any packet header other than the ``common'' header(see below, Section~\ref{sec:commonhdr}),the accessing code must obtain the appropriate header offset.This is accomplished by declaring and bindingthe integer variable \code{off_\tup{hdrname}_}where \code{\tup{hdrname}} refers to a shorthand nameof the header of interest which must match thename assigned in \nsf{tcl/lib/ns-packet.tcl}.This is performed above by the RTPAgent's constructor.Generally, one header object for each type of headerin the simulation is instantiated at simulator run-time.A particular header is enabled via OTcl in the simulation duringsimulator configuration time (see Section~\ref{sec:configpacket}).The static object \code{class_rtphdr} of\clsref{RTPHeaderClass}{../ns-2/rtp.cc} is used to provide linkage to OTcl when the RTP header isenabled at configuration time.When the simulator executes, this static object callsthe \code{PacketHeaderClass} constructor with arguments\code{"PacketHeader/RTP"} and \code{sizeof(hdr_rtp)}.This causes the size of the RTP header to be storedand made available to the packet header managerat configuration time (see below, Section~\ref{sec:packethdrmgr}).The sample member function \fcn[]{sendpkt} methodof \code{RTPAgent} creates a new packetto send by calling \fcn[]{allocpkt}, which handles assignmentof all the network-layer packet header fields (in this case, IP).Headers other than IP are handled separately.In this case, the agent uses the \code{RTPHeader} defined above.The \fcn{Packet::access} member function returns the addressof the first byte in a buffer used to hold header information (see below).Its return value is cast as a pointer to the header of interest,after which member functions of the \code{RTPHeader}object are used to access individual fields.\subsection{Adding a New Packet Header Type}Assuming we wish to create a new header called \code{newhdr}the following steps are performed:\begin{enumerate}\itemsep0pt \item create a new structure defining the raw fields (called \code{hdr_newhdr}) \item define member functions for needed fields \item create a static class to perform OTcl linkage (defines \code{PacketHeader/Newhdr}) \item edit \nsf{tcl/lib/ns-packet.tcl} to enable new packet format (see \ref{sec:pinfoclass}, \ref{sec:configpacket})\end{enumerate}\section{Packet Classes}\label{sec:packetclasses}There are four C++ classes relevant to the handling of packetsand packet headers in general: \code{Packet}, \code{p_info}\code{PacketHeader}, and \code{PacketHeaderManager}.The \clsref{Packet}{../ns-2/packet.h}defines the type for all packets in the simulation;it is a subclass of \code{Event} so that packets maybe scheduled (e.g.~for later arrival at some queue).The \clsref{packet\_info}{../ns-2/packet.h} holds all textrepresentations for packet names.The \clsref{PacketHeader}{../ns-2/packet.h} provides a base class forany packet header configured into the simulation.It essentially provides enough internal state to locate any particular packetheader in the collection of packet headers present in any given packet.The \clsref{PacketHeaderManager}{../ns-2/packet.h}defines a class used to collect and manage currently-configured headers.It is invoked by a method available to OTcl at simulation configurationtime to enable some subset of the compiled-in packet headers.\subsection{The Packet Class}\label{sec:packetclass}The class Packet defines the structure of apacket and provides member functions to handle afree list for objects of this type.It is illustrated in Figure~\ref{pic:packet} anddefined as follows in \code{packet.h}:\begin{figure}[h] \centerline{\includegraphics{packet}} \caption{A Packet Object} \label{pic:packet}\end{figure}\begin{program} class Packet : public Event \{ private: friend class PacketQueue; u_char* bits_; u_char* data_; \* variable size buffer for 'data' */ u_int datalen_; \* length of variable size buffer */ protected: static Packet* free_; public: Packet* next_; \* for queues and the free list */ static int hdrlen_; Packet() : bits_(0), datalen_(0), next_(0) \{\} u_char* const bits() \{ return (bits_); \} Packet* copy() const; static Packet* alloc(); static Packet* alloc(int); inline void allocdata(int); static void free(Packet*); inline u_char* access(int off) \{ if (off < 0) abort(); return (&bits_[off]); \} inline u_char* accessdata() \{ return data_; \} \};\end{program}This class holds a pointer to a generic array of unsignedcharacters (commonly called the ``bag of bits'' or BOB for short)where packet header fields are stored.It also holds a pointer to packet ``data'' (which is often not used insimulations).The \code{bits_} variable contains the address ofthe first byte of the BOB.Effectively BOB is (currently implemented as) a concatenationof all the structures defined for each packet header (by convention,the structures with names beginning \code{hdr_\tup{something}}) that havebeen configured in.BOB generally remains a fixed size throughout a simulation, andthe size is recorded in the \code{Packet::hdrlen_} membervariable.This size is updated during simulator configuration byOTcl\footnote{It is not intended to be updated after configurationtime. Doing so {\em should} be possible, but is currently untested.}.The other methods of the class Packet are for creating newpackets and storing old (unused) ones on a private free list.Such allocation and deallocation is performed by thefollowing code (in \nsf{packet.h}):\begin{program} inline Packet* Packet::alloc() \{ Packet* p = free_; if (p != 0) free_ = p->next_; else \{ p = new Packet; p->bits_ = new u_char[hdrsize_]; if (p == 0 || p->bits_ == 0) abort(); \} return (p); \} /* {\cf allocate a packet with an n byte data buffer} */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -