⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 trace.cc

📁 ns2下用于802.11的无线传输模型的代码 增加了基于信噪比计算差错率等功能
💻 CC
字号:
/* -*-	Mode:C++; c-basic-offset:8; tab-width:8 -*- *//* * Copyright (c) 1990-1997 Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the Computer Systems *	Engineering Group at Lawrence Berkeley Laboratory. * 4. Neither the name of the University nor of the Laboratory may be used *    to endorse or promote products derived from this software without *    specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/trace/trace.cc,v 1.76 2002/10/08 22:15:09 buchheim Exp $ (LBL) */#include <stdio.h>#include <stdlib.h>#include "packet.h"#include "ip.h"#include "tcp.h"#include "rtp.h"#include "srm.h"#include "tfrc.h"#include "flags.h"#include "address.h"#include "trace.h"#include "rap/rap.h"//const double Trace::PRECISION = 1.0e+6; class TraceClass : public TclClass {public:	TraceClass() : TclClass("Trace") { }	TclObject* create(int argc, const char*const* argv) {		if (argc >= 5)			return (new Trace(*argv[4]));		return 0;	}} trace_class;Trace::Trace(int type)	: Connector(), callback_(0), pt_(0), type_(type){	bind("src_", (int*)&src_);	bind("dst_", (int*)&dst_);	bind("callback_", &callback_);	bind("show_tcphdr_", &show_tcphdr_);	pt_ = new BaseTrace;}Trace::~Trace(){}/* * $trace detach * $trace flush * $trace attach $fileID */int Trace::command(int argc, const char*const* argv){	Tcl& tcl = Tcl::instance();	if (argc == 2) {		if (strcmp(argv[1], "detach") == 0) {			pt_->channel(0) ;			pt_->namchannel(0) ;			return (TCL_OK);		}		if (strcmp(argv[1], "flush") == 0) {			Tcl_Channel ch = pt_->channel();			Tcl_Channel namch = pt_->namchannel();			if (ch != 0) 				pt_->flush(ch);				//Tcl_Flush(pt_.channel());			if (namch != 0)				//Tcl_Flush(pt_->namchannel());				pt_->flush(namch);			return (TCL_OK);		}                if (strcmp(argv[1], "tagged") == 0) {			tcl.resultf("%d", pt_->tagged());                        return (TCL_OK);                }	} else if (argc == 3) {		if (strcmp(argv[1], "annotate") == 0) {			if (pt_->channel() != 0)				annotate(argv[2]);			return (TCL_OK);		}		if (strcmp(argv[1], "attach") == 0) {			int mode;			const char* id = argv[2];			Tcl_Channel ch = Tcl_GetChannel(tcl.interp(), (char*)id,						  &mode);			pt_->channel(ch); 			if (pt_->channel() == 0) {				tcl.resultf("trace: can't attach %s for writing", id);				return (TCL_ERROR);			}			return (TCL_OK);		}		if (strcmp(argv[1], "namattach") == 0) {			int mode;			const char* id = argv[2];			Tcl_Channel namch = Tcl_GetChannel(tcl.interp(), 							   (char*)id, &mode);			pt_->namchannel(namch); 			if (pt_->namchannel() == 0) {				tcl.resultf("trace: can't attach %s for writing", id);				return (TCL_ERROR);			}			return (TCL_OK);		}		if (strcmp(argv[1], "ntrace") == 0) {			if (pt_->namchannel() != 0) 				write_nam_trace(argv[2]);			return (TCL_OK);		}		if (strcmp(argv[1], "tagged") == 0) {                        int tag;			if (Tcl_GetBoolean(tcl.interp(),					   (char*)argv[2], &tag) == TCL_OK) {				pt_->tagged(tag);				return (TCL_OK);			} else return (TCL_ERROR);                }	}	return (Connector::command(argc, argv));}void Trace::write_nam_trace(const char *s){	sprintf(pt_->nbuffer(), "%s", s);	pt_->namdump();}void Trace::annotate(const char* s){	if (pt_->tagged()) {		sprintf(pt_->buffer(),			"v "TIME_FORMAT" -e {sim_annotation %g %s}",			Scheduler::instance().clock(), 			Scheduler::instance().clock(), s);	} else {		sprintf(pt_->buffer(),			"v "TIME_FORMAT" eval {set sim_annotation {%s}}", 			pt_->round(Scheduler::instance().clock()), s);	}	pt_->dump();	callback();	sprintf(pt_->nbuffer(), "v -t "TIME_FORMAT" -e sim_annotation %g %s", 		Scheduler::instance().clock(), 		Scheduler::instance().clock(), s);	pt_->namdump();}//Added by Wu Xiuchao to export annotation function.void Trace::write_annotation(const char*s){	sprintf(pt_->buffer(),"%s",s);	pt_->dump();	callback();	//annotate(s);}//endchar* srm_names[] = {        SRM_NAMES};intTrace::get_seqno(Packet* p){	hdr_cmn *th = hdr_cmn::access(p);	hdr_tcp *tcph = hdr_tcp::access(p);	hdr_rtp *rh = hdr_rtp::access(p);        hdr_rap *raph = hdr_rap::access(p);	hdr_tfrc *tfrch = hdr_tfrc::access(p);	packet_t t = th->ptype();	int seqno;	/* UDP's now have seqno's too */	if (t == PT_RTP || t == PT_CBR || t == PT_UDP || t == PT_EXP ||	    t == PT_PARETO)		seqno = rh->seqno();        else if (t == PT_RAP_DATA || t == PT_RAP_ACK)                seqno = raph->seqno();	else if (t == PT_TCP || t == PT_ACK || t == PT_HTTP || t == PT_FTP ||	    t == PT_TELNET)		seqno = tcph->seqno();	else if (t == PT_TFRC)		seqno = tfrch->seqno;	else		seqno = -1; 	return seqno;}// this function should retain some backward-compatibility, so that// scripts don't break.void Trace::format(int tt, int s, int d, Packet* p){	hdr_cmn *th = hdr_cmn::access(p);	hdr_ip *iph = hdr_ip::access(p);	hdr_tcp *tcph = hdr_tcp::access(p);	hdr_srm *sh = hdr_srm::access(p); 	const char* sname = "null";	packet_t t = th->ptype();	const char* name = packet_info.name(t);        /* SRM-specific */	if (strcmp(name,"SRM") == 0 || strcmp(name,"cbr") == 0 || strcmp(name,"udp") == 0) {            if ( sh->type() < 5 && sh->type() > 0 ) {	        sname = srm_names[sh->type()];	    }	}	if (name == 0)		abort();	int seqno = get_seqno(p);        /*          * When new flags are added, make sure to change NUMFLAGS         * in trace.h         */        char flags[NUMFLAGS+1];        for (int i = 0; i < NUMFLAGS; i++)		flags[i] = '-';        flags[NUMFLAGS] = 0;	hdr_flags* hf = hdr_flags::access(p);	flags[0] = hf->ecn_ ? 'C' : '-';          // Ecn Echo	flags[1] = hf->pri_ ? 'P' : '-'; 	flags[2] = '-';	flags[3] = hf->cong_action_ ? 'A' : '-';   // Congestion Action	flags[4] = hf->ecn_to_echo_ ? 'E' : '-';   // Congestion Experienced	flags[5] = hf->fs_ ? 'F' : '-';		   // Fast start: see tcp-fs and tcp-int	flags[6] = hf->ecn_capable_ ? 'N' : '-';	#ifdef notdef	flags[1] = (iph->flags() & PF_PRI) ? 'P' : '-';	flags[2] = (iph->flags() & PF_USR1) ? '1' : '-';	flags[3] = (iph->flags() & PF_USR2) ? '2' : '-';	flags[5] = 0;#endif	char *src_nodeaddr = Address::instance().print_nodeaddr(iph->saddr());	char *src_portaddr = Address::instance().print_portaddr(iph->sport());	char *dst_nodeaddr = Address::instance().print_nodeaddr(iph->daddr());	char *dst_portaddr = Address::instance().print_portaddr(iph->dport());	if (pt_->tagged()) {		sprintf(pt_->buffer(), 			"%c "TIME_FORMAT" -s %d -d %d -p %s -e %d -c %d -i %d -a %d -x {%s.%s %s.%s %d %s %s}",			tt,			Scheduler::instance().clock(),			s, 			d,			name,			th->size(),			iph->flowid(),			th->uid(),			iph->flowid(),			src_nodeaddr,			src_portaddr,			dst_nodeaddr,			dst_portaddr,			seqno,flags,sname);	} else if (!show_tcphdr_) {		sprintf(pt_->buffer(), "%c "TIME_FORMAT" %d %d %s %d %s %d %s.%s %s.%s %d %d",			tt,			pt_->round(Scheduler::instance().clock()),			s,			d,			name,			th->size(),			flags,			iph->flowid() /* was p->class_ */,			// iph->src() >> (Address::instance().NodeShift_[1]),                         // iph->src() & (Address::instance().PortMask_),                         // iph->dst() >> (Address::instance().NodeShift_[1]),                         // iph->dst() & (Address::instance().PortMask_),			src_nodeaddr,			src_portaddr,			dst_nodeaddr,			dst_portaddr,			seqno,			th->uid() /* was p->uid_ */);	} else {		sprintf(pt_->buffer(), 			"%c "TIME_FORMAT" %d %d %s %d %s %d %s.%s %s.%s %d %d %d 0x%x %d %d",			tt,			pt_->round(Scheduler::instance().clock()),			s,			d,			name,			th->size(),			flags,			iph->flowid(), /* was p->class_ */		        // iph->src() >> (Address::instance().NodeShift_[1]), 			// iph->src() & (Address::instance().PortMask_),   		        // iph->dst() >> (Address::instance().NodeShift_[1]),   		        // iph->dst() & (Address::instance().PortMask_),			src_nodeaddr,			src_portaddr,			dst_nodeaddr,			dst_portaddr,			seqno,			th->uid(), /* was p->uid_ */			tcph->ackno(),			tcph->flags(),			tcph->hlen(),			tcph->sa_length());	}	if (pt_->namchannel() != 0)		sprintf(pt_->nbuffer(), 			"%c -t "TIME_FORMAT" -s %d -d %d -p %s -e %d -c %d -i %d -a %d -x {%s.%s %s.%s %d %s %s}",			tt,			Scheduler::instance().clock(),			s, 			d,			name,			th->size(),			iph->flowid(),			th->uid(),			iph->flowid(),			src_nodeaddr,			src_portaddr,			dst_nodeaddr,			dst_portaddr,			seqno,flags,sname);	delete [] src_nodeaddr;  	delete [] src_portaddr;  	delete [] dst_nodeaddr;   	delete [] dst_portaddr;}void Trace::recv(Packet* p, Handler* h){	format(type_, src_, dst_, p);	pt_->dump();	callback();	pt_->namdump();	/* hack: if trace object not attached to anything free packet */	if (target_ == 0)		Packet::free(p);	else		send(p, h);}void Trace::recvOnly(Packet *p){	format(type_, src_, dst_, p);	pt_->dump();	callback();	pt_->namdump();		target_->recvOnly(p);}void Trace::trace(TracedVar* var){	char tmp[256] = "";	Scheduler& s = Scheduler::instance();	if (&s == 0)		return;	if (pt_->tagged()) {		sprintf(pt_->buffer(), "%c "TIME_FORMAT" -a %s -n %s -v %s",			type_,			pt_->round(s.clock()),			var->owner()->name(),			var->name(),			var->value(tmp, 256));	} else {		// format: use Mark's nam feature code without the '-' prefix		sprintf(pt_->buffer(), "%c t"TIME_FORMAT" a%s n%s v%s",			type_,			pt_->round(s.clock()),			var->owner()->name(),			var->name(),			var->value(tmp, 256));	}	pt_->dump();	callback();}void Trace::callback() {	if (callback_) {		Tcl& tcl = Tcl::instance();		tcl.evalf("%s handle { %s }", name(), pt_->buffer());	}}//// we need a DequeTraceClass here because a 'h' event need to go together// with the '-' event. It's possible to use a postprocessing script, but // seems that's inconvient.//static class DequeTraceClass : public TclClass {public:	DequeTraceClass() : TclClass("Trace/Deque") { }	TclObject* create(int args, const char*const* argv) {		if (args >= 5)			return (new DequeTrace(*argv[4]));		return NULL;	}} dequetrace_class;DequeTrace::~DequeTrace(){}void DequeTrace::recv(Packet* p, Handler* h){	// write the '-' event first	format(type_, src_, dst_, p);	pt_->dump();	callback();	pt_->namdump();	if (pt_->namchannel() != 0 ||	    (pt_->tagged() && pt_->channel() !=0)) {		hdr_cmn *th = hdr_cmn::access(p);		hdr_ip *iph = hdr_ip::access(p);		hdr_srm *sh = hdr_srm::access(p);		const char* sname = "null";   		packet_t t = th->ptype();		const char* name = packet_info.name(t);				if (strcmp(name,"SRM") == 0 || strcmp(name,"cbr") == 0 || strcmp(name,"udp") == 0) {		    if ( sh->type() < 5 && sh->type() > 0  ) {		        sname = srm_names[sh->type()];		    }		}   		char *src_nodeaddr = Address::instance().print_nodeaddr(iph->saddr());		char *src_portaddr = Address::instance().print_portaddr(iph->sport());		char *dst_nodeaddr = Address::instance().print_nodeaddr(iph->daddr());		char *dst_portaddr = Address::instance().print_portaddr(iph->dport());		char flags[NUMFLAGS+1];		for (int i = 0; i < NUMFLAGS; i++)			flags[i] = '-';		flags[NUMFLAGS] = 0;		hdr_flags* hf = hdr_flags::access(p);		flags[0] = hf->ecn_ ? 'C' : '-';          // Ecn Echo		flags[1] = hf->pri_ ? 'P' : '-'; 		flags[2] = '-';		flags[3] = hf->cong_action_ ? 'A' : '-';   // Congestion Action		flags[4] = hf->ecn_to_echo_ ? 'E' : '-';   // Congestion Experienced		flags[5] = hf->fs_ ? 'F' : '-';		flags[6] = hf->ecn_capable_ ? 'N' : '-';	#ifdef notdef		flags[1] = (iph->flags() & PF_PRI) ? 'P' : '-';		flags[2] = (iph->flags() & PF_USR1) ? '1' : '-';		flags[3] = (iph->flags() & PF_USR2) ? '2' : '-';		flags[5] = 0;#endif				if (pt_->nbuffer() != 0) {			sprintf(pt_->nbuffer(), 				"%c -t "TIME_FORMAT" -s %d -d %d -p %s -e %d -c %d -i %d -a %d -x {%s.%s %s.%s %d %s %s}",				'h',				Scheduler::instance().clock(),				src_,  				dst_,				name,				th->size(),				iph->flowid(),				th->uid(),				iph->flowid(),				src_nodeaddr,				src_portaddr,				dst_nodeaddr,				dst_portaddr,				-1, flags, sname);			pt_->namdump();		}		if (pt_->tagged() && pt_->buffer() != 0) {			sprintf(pt_->buffer(), 				"%c "TIME_FORMAT" -s %d -d %d -p %s -e %d -c %d -i %d -a %d -x {%s.%s %s.%s %d %s %s}",				'h',				Scheduler::instance().clock(),				src_,	  			dst_,				name,				th->size(),				iph->flowid(),				th->uid(),				iph->flowid(),				src_nodeaddr,				src_portaddr,				dst_nodeaddr,				dst_portaddr,				-1, flags, sname);			pt_->dump();		}		delete [] src_nodeaddr;		delete [] src_portaddr;		delete [] dst_nodeaddr;		delete [] dst_portaddr;	}	/* hack: if trace object not attached to anything free packet */	if (target_ == 0)		Packet::free(p);	else		send(p, h);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -