📄 packet_format.tex
字号:
\begin{verbatim} 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); } /* allocate a packet with an n byte data buffer */ inline Packet* Packet::alloc(int n) { Packet* p = alloc(); if (n > 0) p->allocdata(n); return (p); } /* allocate an n byte data buffer to an existing packet */ inline void Packet::allocdata(int n) { datalen_ = n; data_ = new u_char[n]; if (data_ == 0) abort(); } inline void Packet::free(Packet* p) { p->next_ = free_; free_ = p; if (p->datalen_) { delete p->data_; p->datalen_ = 0; } } inline Packet* Packet::copy() const { Packet* p = alloc(); memcpy(p->bits(), bits_, hdrlen_); if (datalen_) { p->datalen_ = datalen_; p->data_ = new u_char[datalen_]; memcpy(p->data_, data_, datalen_); } return (p); }\end{verbatim}\end{small}The \code{alloc} method is a support function commonlyused to create new packets.It is most often called by the \code{Agent::allocpkt()} method onbehalf of agents and is thus not normally invoked directly by most objects.It first attempts to locate an old packet on the free list andif this fails allocates a new one using the C++ \code{new} operator.Note that \code{Packet} class objects and BOBs areallocated separately.The \code{free} method frees a packet by returning it to the freelist.Note that {\bf packets are never returned to the system's memoryallocator}.Instead, they are stored on a free list when \code{Packet::free} is called.The \code{copy} member creates a new, identical copy of a packetwith the exception of the \code{uid} field, which is unique.This function is used by \code{Replicator} objects to supportmulticast distribution and LANs.\subsubsection{\shdr{the hdr\_cmn class}{packet.h}{sec:commonhdr}}Each packet in the simulator has a ``common''header which is defined in \code{packet.h} as follows:\begin{small}\begin{verbatim} struct hdr_cmn { double ts_; // timestamp: for q-delay measurement int ptype_; // packet type (see above) int uid_; // unique id int size_; // simulated packet size int iface_; // receiving interface (label) /* per-field member functions */ int& ptype() { return (ptype_); } int& uid() { return (uid_); } int& size() { return (size_); } int& iface() { return (iface_); } double& timestamp() { return (ts_); } }; \end{verbatim}\end{small}This structure primarily defines fields used for tracingthe flow of packets or measuring other quantities.The time stamp field is used to measure queueing delayat switch nodes.The \code{ptype_} field is used to identify thetype of packets, which makes reading traces simpler.The \code{uid_} field is used by the scheduler in schedulingpacket arrivals.The \code{size_} field is of general use and gives thesimulated packet's size.Note that the actual number of bytes consumed in the simulationmay not relate to the value of this field.Rather, it is used most often in computing the time required for a packetto be delivered along a network link.The \code{iface_} field is used by the simulator when performingmulticast distribution tree computations.It is a label indicating (typically) on which link a packet was received.\subsubsection{\shdr{the PacketHeaderManager class}{packet.cc}{sec:packethdrmgr}}An object of the class \code{PacketHeaderManager} is usedto manage the set of currently-active packet header types andassign each of them unique offsets in the BOB.It is defined in both the C++ and OTcl code:\begin{small}\begin{verbatim}From tcl/lib/ns-packet.h: 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 }From packet.cc: /* manages active packet header types */ class PacketHeaderManager : public TclObject { public: PacketHeaderManager() { bind("hdrlen_", &Packet::hdrlen_); } };\end{verbatim}\end{small}The code in \code{ns-packet.tcl} is executed when thesimulator initializes.Thus, the {\tt foreach} statement is executed before thesimulation begins, and initializes the OTcl class array\code{vartab_} to contain the mapping between classthe name and the name of the variable used to containthat class's header in a packet (which is initialized later).For example, the value of \code{vartab_(IP)} is set to\code{off_ip_}.The \code{create_packetformat} instance procedure is part of thebasic Simulator class and is called one time during simulatorconfiguration.It first creates a single \code{PacketHeaderManager} object.The C++ constructor links the OTcl instancevariable \code{hdrlen_} (of class \code{PacketHeaderManager})to the C++ variable \code{Packet::hdrlen_} (a staticmember of the \code{Packet} class).This has the effect of setting \code{Packet::hdrlen_} tozero.Note that binding across class types in this fashion isunusual.\label{sec:configpacket}After creating the packet manager, the \code{foreach}loop enables each of the packet headers of interest.This loop iterates through the list of definedpacket headers of the form$(h_i, o_i)$ where $h_i$ is the name of the $i$th headerand $o_i$ is the name of the variable containing thelocation of the $h_i$ header in BOB.The placement of headers is performed by the \code{allochdr}instproc of the \code{PacketHeaderManager} OTcl class.The procedure keeps a running variable \code{hdrlen_} withthe current length of BOB as new packet headers are enabled.It also arranges for 8-byte alignment for any newly-enabled packetheader.This is needed to ensure that when double-world length quantitiesare used in packet headers on machines where double-word alignmentis required, access faults are not produced.\footnote{Insome processer architectures, including theSparc and HP-PA, double-word access must be performed on a double-wordboundary (i.e. addresses ending in 0 mod 8). Attempting to performunaligned accesses result in an abnormal program termination.}.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -