00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef lint
00020 static const char rcsid[] =
00021 "@(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/trace/traffictrace.cc,v 1.15 2002/12/10 01:33:39 difa Exp $ (Xerox)";
00022 #endif
00023
00024
00025
00026
00027
00028
00029 #include <sys/types.h>
00030 #include <sys/stat.h>
00031 #include <stdio.h>
00032
00033 #include "config.h"
00034 #ifdef HAVE_NETINET_IN_H
00035 #include <netinet/in.h>
00036 #endif
00037
00038
00039 #include "random.h"
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 #include "object.h"
00050 #include "trafgen.h"
00051
00052 struct tracerec {
00053 u_int32_t trec_time;
00054 u_int32_t trec_size;
00055 };
00056
00057
00058
00059
00060 class TraceFile : public NsObject {
00061 public:
00062 TraceFile();
00063 void get_next(int&, struct tracerec&);
00064
00065
00066 int setup();
00067 int command(int argc, const char*const* argv);
00068 private:
00069 void recv(Packet*, Handler*);
00070 int status_;
00071 char *name_;
00072 int nrec_;
00073 struct tracerec *trace_;
00074 };
00075
00076
00077
00078
00079
00080 class TrafficTrace : public TrafficGenerator {
00081 public:
00082 TrafficTrace();
00083 int command(int argc, const char*const* argv);
00084 virtual double next_interval(int &);
00085 protected:
00086 void timeout();
00087 TraceFile *tfile_;
00088 struct tracerec trec_;
00089 int ndx_;
00090 void init();
00091 };
00092
00093
00094 static class TraceFileClass : public TclClass {
00095 public:
00096 TraceFileClass() : TclClass("Tracefile") {}
00097 TclObject* create(int, const char*const*) {
00098 return (new TraceFile());
00099 }
00100 } class_tracefile;
00101
00102 TraceFile::TraceFile() : status_(0)
00103 {
00104 }
00105
00106 int TraceFile::command(int argc, const char*const* argv)
00107 {
00108
00109 if (argc == 3) {
00110 if (strcmp(argv[1], "filename") == 0) {
00111 name_ = new char[strlen(argv[2])+1];
00112 strcpy(name_, argv[2]);
00113 return(TCL_OK);
00114 }
00115 }
00116 return (NsObject::command(argc, argv));
00117 }
00118
00119 void TraceFile::get_next(int& ndx, struct tracerec& t)
00120 {
00121 t.trec_time = trace_[ndx].trec_time;
00122 t.trec_size = trace_[ndx].trec_size;
00123
00124 if (++ndx == nrec_)
00125 ndx = 0;
00126
00127 }
00128
00129 int TraceFile::setup()
00130 {
00131 tracerec* t;
00132 struct stat buf;
00133 int i;
00134 FILE *fp;
00135
00136
00137
00138
00139 if (! status_) {
00140 status_ = 1;
00141
00142 if (stat(name_, (struct stat *)&buf)) {
00143 printf("could not stat %s\n", name_);
00144 return -1;
00145 }
00146
00147 nrec_ = buf.st_size/sizeof(tracerec);
00148 unsigned nrecplus = nrec_ * sizeof(tracerec);
00149 unsigned bufst = buf.st_size;
00150
00151
00152 if (nrecplus != bufst) {
00153 printf("bad file size in %s\n", name_);
00154 return -1;
00155 }
00156
00157 trace_ = new struct tracerec[nrec_];
00158
00159 if ((fp = fopen(name_, "rb")) == NULL) {
00160 printf("can't open file %s\n", name_);
00161 return -1;
00162 }
00163
00164 for (i = 0, t = trace_; i < nrec_; i++, t++)
00165 if (fread((char *)t, sizeof(tracerec), 1, fp) != 1) {
00166 printf("read failed\n");
00167 return -1 ;
00168 }
00169 else {
00170
00171 t->trec_time = ntohl(t->trec_time);
00172 t->trec_size = ntohl(t->trec_size);
00173 }
00174
00175 }
00176
00177
00178 return (int(Random::uniform((double)nrec_)+.5));
00179
00180 }
00181
00182 void TraceFile::recv(Packet*, Handler*)
00183 {
00184
00185 abort();
00186 }
00187
00188
00189
00190 static class TrafficTraceClass : public TclClass {
00191 public:
00192 TrafficTraceClass() : TclClass("Application/Traffic/Trace") {}
00193 TclObject* create(int, const char*const*) {
00194 return(new TrafficTrace());
00195 }
00196 } class_traffictrace;
00197
00198 TrafficTrace::TrafficTrace()
00199 {
00200 tfile_ = (TraceFile *)NULL;
00201 }
00202
00203 void TrafficTrace::init()
00204 {
00205 if (tfile_)
00206 ndx_ = tfile_->setup();
00207 }
00208
00209 int TrafficTrace::command(int argc, const char*const* argv)
00210 {
00211 Tcl& tcl = Tcl::instance();
00212
00213 if (argc == 3) {
00214 if (strcmp(argv[1], "attach-tracefile") == 0) {
00215 tfile_ = (TraceFile *)TclObject::lookup(argv[2]);
00216 if (tfile_ == 0) {
00217 tcl.resultf("no such node %s", argv[2]);
00218 return(TCL_ERROR);
00219 }
00220 return(TCL_OK);
00221 }
00222 }
00223
00224 return (TrafficGenerator::command(argc, argv));
00225
00226 }
00227
00228 void TrafficTrace::timeout()
00229 {
00230 if (! running_)
00231 return;
00232
00233
00234
00235
00236
00237 agent_->sendmsg(size_);
00238
00239 nextPkttime_ = next_interval(size_);
00240
00241 timer_.resched(nextPkttime_);
00242 }
00243
00244
00245 double TrafficTrace::next_interval(int& size)
00246 {
00247 tfile_->get_next(ndx_, trec_);
00248 size = trec_.trec_size;
00249 return(((double)trec_.trec_time)/1000000.0);
00250 }