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