📄 trace.tex
字号:
public: Trace(int type); ~Trace(); int command(int argc, const char*const* argv); void recv(Packet* p, Handler*); void dump(); inline char* buffer() \{ return (wrk_); \} \};\end{program}The \code{src\_}, and \code{dst\_} internal state is usedto label trace output and is independent of the corresponding fieldnames in packet headers.The main \fcn[]{recv} method is defined as follows:\begin{program} void Trace::recv(Packet* p, Handler* h) \{ format(type_, src_, dst_, p); dump(); /* {\cf hack: if trace object not attached to anything free packet} */ if (target_ == 0) Packet::free(p); else send(p, h); /* \fcn[]{Connector::send} */ \}\end{program}The function merely formats a trace entry using the source, destination,and particular trace type character.The \code{dump} function writes the formatted entry out to theI/O handle associated with \code{channel\_}.The \code{format} function, in effect, dictates the trace file format.\section{Trace File Format}\label{sec:traceformat}The \fcn[]{Trace::format} method defines the trace file format usedin trace files produced by the \code{Trace} class.It is constructed to maintain backward compatibility with output filesin earlier versions of the simulator (\ie, \ns~v1) so that \ns~v1post-processing scripts continue to operate.The important pieces of its implementation are as follows:\begin{program} // {\cf this function should retain some backward-compatibility, so that} // {\cf scripts don't break.} void Trace::format(int tt, int s, int d, Packet* p) \{ hdr_cmn *th = (hdr_cmn*)p->access(off_cmn_); hdr_ip *iph = (hdr_ip*)p->access(off_ip_); hdr_tcp *tcph = (hdr_tcp*)p->access(off_tcp_); hdr_rtp *rh = (hdr_rtp*)p->access(off_rtp_); packet_t t = th->ptype(); const char* name = packet_info.name(t); if (name == 0) abort(); int seqno; /* XXX */ /* {\cf CBR's now have seqno's too} */ if (t == PT_RTP || t == PT_CBR) seqno = rh->seqno(); else if (t == PT_TCP || t == PT_ACK) seqno = tcph->seqno(); else seqno = -1; \ldots if (!show_tcphdr_) \{ sprintf(wrk_, "%c %g %d %d %s %d %s %d %d.%d %d.%d %d %d", tt, Scheduler::instance().clock(), s, d, name, th->size(), flags, iph->flowid() /* was p->class_ */, iph->src() >> 8, iph->src() & 0xff, // XXX iph->dst() >> 8, iph->dst() & 0xff, // XXX seqno, th->uid() /* was p->uid_ */); \} else \{ sprintf(wrk_, "%c %g %d %d %s %d %s %d %d.%d %d.%d %d %d %d 0x%x %d", tt, Scheduler::instance().clock(), s, d, name, th->size(), flags, iph->flowid() /* was p->class_ */, iph->src() >> 8, iph->src() & 0xff, // XXX iph->dst() >> 8, iph->dst() & 0xff, // XXX seqno, th->uid(), /* was p->uid_ */ tcph->ackno(), tcph->flags(), tcph->hlen()); \}\end{program}This function is somewhat unelegant, primarily due to the desireto maintain backward compatibility.It formats the source, destination, and type fields defined in thetrace object ({\em not in the packet headers}), the current time,along with various packet header fields including,type of packet (as a name), size, flags (symbolically),flow identifier, source and destination packet header fields,sequence number (if present), and unique identifier.The \code{show_tcphdr_} variable indicates whether the traceoutput should append tcp header information (ack number, flags, header length)at the end of each output line.This is especially useful for simulations using\href{FullTCP agents}{Section}{sec:fulltcp}.An example of a trace file (without the tcp header fields) mighappear as follows: \begin{small}\begin{verbatim}+ 1.84375 0 2 cbr 210 ------- 0 0.0 3.1 225 610- 1.84375 0 2 cbr 210 ------- 0 0.0 3.1 225 610r 1.84471 2 1 cbr 210 ------- 1 3.0 1.0 195 600r 1.84566 2 0 ack 40 ------- 2 3.2 0.1 82 602+ 1.84566 0 2 tcp 1000 ------- 2 0.1 3.2 102 611- 1.84566 0 2 tcp 1000 ------- 2 0.1 3.2 102 611r 1.84609 0 2 cbr 210 ------- 0 0.0 3.1 225 610+ 1.84609 2 3 cbr 210 ------- 0 0.0 3.1 225 610d 1.84609 2 3 cbr 210 ------- 0 0.0 3.1 225 610- 1.8461 2 3 cbr 210 ------- 0 0.0 3.1 192 511r 1.84612 3 2 cbr 210 ------- 1 3.0 1.0 196 603+ 1.84612 2 1 cbr 210 ------- 1 3.0 1.0 196 603- 1.84612 2 1 cbr 210 ------- 1 3.0 1.0 196 603+ 1.84625 3 2 cbr 210 ------- 1 3.0 1.0 199 612\end{verbatim}\end{small}Here we see 14 trace entries, five enque operations (indicated by ``+''in the first column), four deque operations (indicated by ``-''),four receive events (indicated by ``r''), and one drop event.(this had better be a trace fragment, orsome packets would have just vanished!).The simulated time (in seconds) at which each event occurred is listedin the second column.The next two fields indicate between which two nodes tracing is happening.The next field is \href{a descriptive name for the the type of packet seen}{Section}{sec:traceptype}.The next field is the packet's size, as encoded in its IP header.The next four characters represent special flag bits which may beenabled. Presently only one such bit exists (explicit congestionnotification, or {\sf ECN}). In this example, {\sf ECN} is not used.The next field gives the IP {\em flow identifier} field as definedfor IP version 6.\footnote{In \ns~v1, each packet included a \code{class}field, which was used by CBQ to classify packets.It then found additional use to differentiate between``flows'' at one trace point. In \ns~v2, the flow ID field is availablefor this purpose, but any additional information (which was commonly overloadedinto the class field in \ns~v1) should be placed in its own separate field,possibly in some other header}.The subsequent two fields indicate the packet's source and destinationnode addresses, respectively.The following field indicates the sequence number.\footnote{In \ns~v1,all packets contained a sequence number, whereas in \ns~v2 only thoseAgents interested in providing sequencing will generate sequence numbers.Thus, this field may not be useful in \ns~v2 for packets generated byagents that have not filled in a sequence number. It is used hereto remain backward compatible with \ns~v1.}The last field is a unique packet identifier. Each new packetcreated in the simulation is assigned a new, unique identifier.\section{Packet Types}\label{sec:traceptype}Each packet contains a packet type field used by \code{Trace::format}to print out the type of packet encountered.The type field is defined in the \code{TraceHeader} class, and is consideredto be part of the trace support; it is not interpretedelsewhere in the simulator.Initialization of the type field in packets is performed by the\fcn{Agent::allocpkt} method.The type field is set to integer values associated with thedefinition passed to\href{the \code{Agent} constructor}{Section}{sec:agents:exlinkage}.The currently-supported definitions, their values, and theirassociated symblic names are as follows(defined in \nsf{packet.h}):\begin{program}enum packet_t \{ PT_TCP, PT_UDP, PT_CBR, PT_AUDIO, PT_VIDEO, PT_ACK, PT_START, PT_STOP, PT_PRUNE, PT_GRAFT, PT_GRAFTACK, PT_JOIN, PT_ASSERT, PT_MESSAGE, PT_RTCP, PT_RTP, PT_RTPROTO_DV, PT_CtrMcast_Encap, PT_CtrMcast_Decap, PT_SRM, /* simple signalling messages */ PT_REQUEST, PT_ACCEPT, PT_CONFIRM, PT_TEARDOWN, PT_LIVE, // packet from live network PT_REJECT, PT_TELNET, // not needed: telnet use TCP PT_FTP, PT_PARETO, PT_EXP, PT_INVAL, PT_HTTP, /* new encapsulator */ PT_ENCAPSULATED, PT_MFTP, /* CMU/Monarch's extnsions */ PT_ARP, PT_MAC, PT_TORA, PT_DSR, PT_AODV, // insert new packet types here PT_NTYPE // This MUST be the LAST one\};\end{program}The constructor of class \code{p_info} glues these constants withtheir string values:\begin{program} p_info() \{ name_[PT_TCP]= "tcp"; name_[PT_UDP]= "udp"; name_[PT_CBR]= "cbr"; name_[PT_AUDIO]= "audio"; ... name_[PT_NTYPE]= "undefined"; \}\end{program}See also section~\ref{sec:pinfoclass} for more details.\section{Queue Monitoring}\label{sec:qmonitor}Queue monitoring refers to the capability of tracking thedynamics of packets at a queue (or other object).A queue monitor tracks packet arrival/departure/drop statistics,and may optionally compute averages of these values.Monitoring may be applied all packets (aggregate statistics), orper-flow statistics (using a Flow Monitor).Several classes are used in supporting queue monitoring.When a packet arrives at a link where queue monitoring is enabled,it generally passes through a \code{SnoopQueue} object when itarrives and leaves (or is dropped).These objects contain a reference to a \code{QueueMonitor} object.A \code{QueueMonitor} is defined as follows (\nsf{queue-monitor.cc}):\begin{program} class QueueMonitor : public TclObject \{ public: QueueMonitor() : bytesInt_(NULL), pktsInt_(NULL), delaySamp_(NULL), size_(0), pkts_(0), parrivals_(0), barrivals_(0), pdepartures_(0), bdepartures_(0), pdrops_(0), bdrops_(0), srcId_(0), dstId_(0), channel_(0) \{ bind("size_", &size_); bind("pkts_", &pkts_); bind("parrivals_", &parrivals_); bind("barrivals_", &barrivals_); bind("pdepartures_", &pdepartures_); bind("bdepartures_", &bdepartures_); bind("pdrops_", &pdrops_); bind("bdrops_", &bdrops_); bind("off_cmn_", &off_cmn_); \}; int size() const \{ return (size_); \} int pkts() const \{ return (pkts_); \} int parrivals() const \{ return (parrivals_); \} int barrivals() const \{ return (barrivals_); \} int pdepartures() const \{ return (pdepartures_); \} int bdepartures() const \{ return (bdepartures_); \} int pdrops() const \{ return (pdrops_); \} int bdrops() const \{ return (bdrops_); \} void printStats(); virtual void in(Packet*); virtual void out(Packet*); virtual void drop(Packet*); virtual void edrop(Packet*) \{ abort(); \}; // not here virtual int command(int argc, const char*const* argv); \ldots // {\cf packet arrival to a queue} void QueueMonitor::in(Packet* p) \{ hdr_cmn* hdr = (hdr_cmn*)p->access(off_cmn_); double now = Scheduler::instance().clock(); int pktsz = hdr->size(); barrivals_ += pktsz; parrivals_++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -