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 #ifndef lint
00038 static const char rcsid[] =
00039 "@(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/satellite/sattrace.cc,v 1.16 2005/09/21 20:54:21 haldar Exp $";
00040 #endif
00041
00042 #include <stdio.h>
00043 #include <stdlib.h>
00044 #include "packet.h"
00045 #include "ip.h"
00046 #include "tcp.h"
00047 #include "sctp.h"
00048 #include "rtp.h"
00049 #include "srm.h"
00050 #include "flags.h"
00051 #include "address.h"
00052 #include "trace.h"
00053 #include "sattrace.h"
00054 #include "satposition.h"
00055 #include "satnode.h"
00056 #include "sat-hdlc.h"
00057
00058 class SatTraceClass : public TclClass {
00059 public:
00060 SatTraceClass() : TclClass("Trace/Sat") { }
00061 TclObject* create(int argc, const char*const* argv) {
00062 if (argc >= 5) {
00063 return (new SatTrace(*argv[4]));
00064 }
00065 return 0;
00066 }
00067 } sat_trace_class;
00068
00069
00070 char* srm_names_[] = {
00071 SRM_NAMES
00072 };
00073
00074 void SatTrace::format_hdlc(Packet *p, int offset)
00075 {
00076 struct hdr_hdlc *hh = HDR_HDLC(p);
00077 struct I_frame *ifr = (struct I_frame *)&(hh->hdlc_fc_);
00078 struct S_frame *sf = (struct S_frame *)&(hh->hdlc_fc_);
00079 struct U_frame *uf = (struct U_frame *)&(hh->hdlc_fc_);
00080
00081 switch(hh->fc_type_) {
00082 case HDLC_I_frame:
00083 if (pt_->tagged()) {
00084 sprintf(pt_->buffer() + offset,
00085 "-hdlc:sa %d -hdlc:da %d -hdlc:ft I -hdlc:r_seq %d -hdlc:s_seq %d",
00086 hh->saddr(),
00087 hh->daddr(),
00088 ifr->recv_seqno,
00089 ifr->send_seqno);
00090
00091
00092
00093
00094
00095
00096
00097
00098 } else {
00099 sprintf(pt_->buffer() + offset,
00100 "[%d %d I %d %d]",
00101 hh->saddr(),
00102 hh->daddr(),
00103 ifr->recv_seqno,
00104 ifr->send_seqno);
00105 }
00106 break;
00107
00108 case HDLC_S_frame:
00109 if (pt_->tagged()) {
00110 sprintf(pt_->buffer() + offset,
00111 "-hdlc:sa %d -hdlc:da %d -hdlc:ft S -hdlc:r_seq %d -hdlc:stype %s",
00112 hh->saddr(),
00113 hh->daddr(),
00114 sf->recv_seqno,
00115 (sf->stype == RR) ? "RR" :
00116 (sf->stype == REJ) ? "REJ" :
00117 (sf->stype == RNR) ? "RNR" :
00118 (sf->stype == SREJ) ? "SREJ" : "UNKN");
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131 } else {
00132 sprintf(pt_->buffer() + offset,
00133 "[%d %d S %d %s]",
00134 hh->saddr(),
00135 hh->daddr(),
00136 sf->recv_seqno,
00137 sf->stype == RR ? "RR" :
00138 sf->stype == REJ ? "REJ" :
00139 sf->stype == RNR ? "RNR" :
00140 sf->stype == SREJ ? "SREJ" :
00141 "UNKN");
00142 }
00143 break;
00144
00145 case HDLC_U_frame:
00146 if (pt_->tagged()) {
00147 sprintf(pt_->buffer() + offset,
00148 "-hdlc:sa %d -hdlc:da %d -hdlc:ft U -hdlc:utype %s",
00149 hh->saddr(),
00150 hh->daddr(),
00151 uf->utype == SABME ? "SABME" :
00152 uf->utype == UA ? "UA" :
00153 uf->utype == DM ? "DM" :
00154 uf->utype == DISC ? "DISC" : "UNKN");
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 } else {
00167 sprintf(pt_->buffer() + offset,
00168 "[%d %d U %s]",
00169 hh->saddr(),
00170 hh->daddr(),
00171 uf->utype == SABME ? "SABME" :
00172 uf->utype == UA ? "UA" :
00173 uf->utype == DM ? "DM" :
00174 uf->utype == DISC ? "DISC" : "UNKN");
00175 }
00176 break;
00177
00178 default:
00179
00180 fprintf(stderr, "Unknown HDLC frame type\n");
00181 exit(1);
00182 }
00183
00184 }
00185
00186
00187
00188 void SatTrace::format(int tt, int s, int d, Packet* p)
00189 {
00190 int offset = 0;
00191 hdr_cmn *th = hdr_cmn::access(p);
00192 hdr_ip *iph = hdr_ip::access(p);
00193 hdr_tcp *tcph = hdr_tcp::access(p);
00194 hdr_sctp *sctph = hdr_sctp::access(p);
00195 hdr_rtp *rh = hdr_rtp::access(p);
00196 hdr_srm *sh = hdr_srm::access(p);
00197
00198 const char* sname = "null";
00199 int lasth, nexth, snadd;
00200 Node* n;
00201
00202 packet_t t = th->ptype();
00203 const char* name = packet_info.name(t);
00204
00205
00206 if (strcmp(name,"SRM") == 0 || strcmp(name,"cbr") == 0 || strcmp(name,"udp") == 0) {
00207 if ( sh->type() < 5 && sh->type() > 0 ) {
00208 sname = srm_names_[sh->type()];
00209 }
00210 }
00211
00212 if (name == 0)
00213 abort();
00214
00215 int seqno;
00216
00217 if (t == PT_RTP || t == PT_CBR || t == PT_UDP || t == PT_EXP ||
00218 t == PT_PARETO)
00219 seqno = rh->seqno();
00220 else if (t == PT_TCP || t == PT_ACK || t == PT_HTTP || t == PT_FTP ||
00221 t == PT_TELNET)
00222 seqno = tcph->seqno();
00223 else
00224 seqno = -1;
00225
00226
00227
00228
00229 char flags[NUMFLAGS+1];
00230 for (int i = 0; i < NUMFLAGS; i++)
00231 flags[i] = '-';
00232 flags[NUMFLAGS] = 0;
00233
00234 hdr_flags* hf = hdr_flags::access(p);
00235 flags[0] = hf->ecn_ ? 'C' : '-';
00236 flags[1] = hf->pri_ ? 'P' : '-';
00237 flags[2] = '-';
00238 flags[3] = hf->cong_action_ ? 'A' : '-';
00239 flags[4] = hf->ecn_to_echo_ ? 'E' : '-';
00240 flags[5] = hf->fs_ ? 'F' : '-';
00241 flags[6] = hf->ecn_capable_ ? 'N' : '-';
00242 flags[7] = 0;
00243
00244 #ifdef notdef
00245 flags[1] = (iph->flags() & PF_PRI) ? 'P' : '-';
00246 flags[2] = (iph->flags() & PF_USR1) ? '1' : '-';
00247 flags[3] = (iph->flags() & PF_USR2) ? '2' : '-';
00248 flags[5] = 0;
00249 #endif
00250 char *src_nodeaddr = Address::instance().print_nodeaddr(iph->saddr());
00251 char *src_portaddr = Address::instance().print_portaddr(iph->sport());
00252 char *dst_nodeaddr = Address::instance().print_nodeaddr(iph->daddr());
00253 char *dst_portaddr = Address::instance().print_portaddr(iph->dport());
00254
00255
00256 double s_lat = -999, s_lon = -999, d_lat = -999, d_lon = -999;
00257 n = Node::nodehead_.lh_first;
00258
00259
00260
00261 assert (n != 0);
00262 lasth = th->last_hop_;
00263 nexth = th->next_hop_;
00264 for (; n; n = n->nextnode() ) {
00265 SatNode *sn = (SatNode*) n;
00266 snadd = sn->address();
00267 if (lasth == snadd) {
00268 s_lat = RAD_TO_DEG(SatGeometry::get_latitude(sn->position()->coord()));
00269 s_lon = RAD_TO_DEG(SatGeometry::get_longitude(sn->position()->coord()));
00270 if (d_lat != -999)
00271 break;
00272 }
00273 if (nexth == snadd) {
00274 d_lat = RAD_TO_DEG(SatGeometry::get_latitude(sn->position()->coord()));
00275 d_lon = RAD_TO_DEG(SatGeometry::get_longitude(sn->position()->coord()));
00276 if (s_lat != -999)
00277 break;
00278 }
00279 }
00280
00281 if (show_sctphdr_ && t == PT_SCTP) {
00282 double timestamp;
00283 timestamp = Scheduler::instance().clock();
00284
00285 for(unsigned int i = 0; i < sctph->NumChunks(); i++) {
00286 switch(sctph->SctpTrace()[i].eType) {
00287 case SCTP_CHUNK_INIT:
00288 case SCTP_CHUNK_INIT_ACK:
00289 case SCTP_CHUNK_COOKIE_ECHO:
00290 case SCTP_CHUNK_COOKIE_ACK:
00291 flags[7] = 'I';
00292 break;
00293
00294 case SCTP_CHUNK_DATA:
00295 flags[7] = 'D';
00296 break;
00297
00298 case SCTP_CHUNK_SACK:
00299 flags[7] = 'S';
00300 break;
00301
00302 case SCTP_CHUNK_FORWARD_TSN:
00303 flags[7] = 'R';
00304 break;
00305
00306 case SCTP_CHUNK_HB:
00307 flags[7] = 'H';
00308 break;
00309
00310 case SCTP_CHUNK_HB_ACK:
00311 flags[7] = 'B';
00312 break;
00313 default:
00314 assert (false);
00315 break;
00316 }
00317 sprintf(pt_->buffer(), "%c %.4f %d %d %s %d %s %d %s.%s %s.%s %d %d %d %d %d %.2f %.2f %.2f %.2f",
00318 tt,
00319 pt_->round(Scheduler::instance().clock()),
00320 lasth,
00321 nexth,
00322 name,
00323 th->size(),
00324 flags,
00325 iph->flowid() ,
00326
00327
00328
00329
00330 src_nodeaddr,
00331 src_portaddr,
00332 dst_nodeaddr,
00333 dst_portaddr,
00334 sctph->NumChunks(),
00335 sctph->SctpTrace()[i].uiTsn,
00336 th->uid(),
00337 sctph->SctpTrace()[i].usStreamId,
00338 sctph->SctpTrace()[i].usStreamSeqNum,
00339 s_lat,
00340 s_lon,
00341 d_lat,
00342 d_lon);
00343
00344
00345
00346
00347
00348 if(i < sctph->NumChunks() - 1)
00349 pt_->dump();
00350 }
00351 }
00352 else if (pt_->tagged()) {
00353 sprintf(pt_->nbuffer(),
00354 "%c %g -s %d -d %d -p %s -e %d -c %d -i %d -a %d -x {%s.%s %s.%s %d %s %s}",
00355 tt,
00356 Scheduler::instance().clock(),
00357 s,
00358 d,
00359 name,
00360 th->size(),
00361 iph->flowid(),
00362 th->uid(),
00363 iph->flowid(),
00364 src_nodeaddr,
00365 src_portaddr,
00366 dst_nodeaddr,
00367 dst_portaddr,
00368 seqno,flags,sname);
00369 } else if (!show_tcphdr_) {
00370 sprintf(pt_->buffer(), "%c %.4f %d %d %s %d %s %d %s.%s %s.%s %d %d %.2f %.2f %.2f %.2f",
00371 tt,
00372 pt_->round(Scheduler::instance().clock()),
00373 lasth,
00374 nexth,
00375 name,
00376 th->size(),
00377 flags,
00378 iph->flowid() ,
00379
00380
00381
00382
00383 src_nodeaddr,
00384 src_portaddr,
00385 dst_nodeaddr,
00386 dst_portaddr,
00387 seqno,
00388 th->uid(),
00389 s_lat,
00390 s_lon,
00391 d_lat,
00392 d_lon);
00393 } else {
00394 sprintf(pt_->buffer(),
00395 "%c %.4f %d %d %s %d %s %d %s.%s %s.%s %d %d %d 0x%x %d %d %.2f %.2f %.2f %.2f",
00396 tt,
00397 pt_->round(Scheduler::instance().clock()),
00398 lasth,
00399 nexth,
00400 name,
00401 th->size(),
00402 flags,
00403 iph->flowid(),
00404
00405
00406
00407
00408 src_nodeaddr,
00409 src_portaddr,
00410 dst_nodeaddr,
00411 dst_portaddr,
00412 seqno,
00413 th->uid(),
00414 tcph->ackno(),
00415 tcph->flags(),
00416 tcph->hlen(),
00417 tcph->sa_length(),
00418 s_lat,
00419 s_lon,
00420 d_lat,
00421 d_lon);
00422 }
00423
00424 offset = strlen(pt_->buffer());
00425 if (t == PT_HDLC)
00426 format_hdlc(p, offset);
00427
00428
00429 if (pt_->namchannel() != 0)
00430 sprintf(pt_->nbuffer(),
00431 "%c -t %g -s %d -d %d -p %s -e %d -c %d -i %d -a %d -x {%s.%s %s.%s %d %s %s}",
00432 tt,
00433 Scheduler::instance().clock(),
00434 s,
00435 d,
00436 name,
00437 th->size(),
00438 iph->flowid(),
00439 th->uid(),
00440 iph->flowid(),
00441 src_nodeaddr,
00442 src_portaddr,
00443 dst_nodeaddr,
00444 dst_portaddr,
00445 seqno,flags,sname);
00446 delete [] src_nodeaddr;
00447 delete [] src_portaddr;
00448 delete [] dst_nodeaddr;
00449 delete [] dst_portaddr;
00450 }
00451
00452 void SatTrace::traceonly(Packet* p)
00453 {
00454 format(type_, src_, dst_, p);
00455 pt_->dump();
00456 }
00457
00458
00459
00460
00461
00462
00463 static class SatDequeTraceClass : public TclClass {
00464 public:
00465 SatDequeTraceClass() : TclClass("Trace/Sat/Deque") { }
00466 TclObject* create(int args, const char*const* argv) {
00467 if (args >= 5)
00468 return (new SatDequeTrace(*argv[4]));
00469 return NULL;
00470 }
00471 } sat_dequetrace_class;
00472
00473
00474 void
00475 SatDequeTrace::recv(Packet* p, Handler* h)
00476 {
00477
00478 format(type_, src_, dst_, p);
00479 pt_->dump();
00480 pt_->namdump();
00481
00482 if (pt_->namchannel() != 0) {
00483 hdr_cmn *th = hdr_cmn::access(p);
00484 hdr_ip *iph = hdr_ip::access(p);
00485 hdr_srm *sh = hdr_srm::access(p);
00486 const char* sname = "null";
00487
00488 packet_t t = th->ptype();
00489 const char* name = packet_info.name(t);
00490
00491 if (strcmp(name,"SRM") == 0 || strcmp(name,"cbr") == 0 || strcmp(name,"udp") == 0) {
00492 if ( sh->type() < 5 && sh->type() > 0 ) {
00493 sname = srm_names_[sh->type()];
00494 }
00495 }
00496
00497 char *src_nodeaddr = Address::instance().print_nodeaddr(iph->saddr());
00498 char *src_portaddr = Address::instance().print_portaddr(iph->sport());
00499 char *dst_nodeaddr = Address::instance().print_nodeaddr(iph->daddr());
00500 char *dst_portaddr = Address::instance().print_portaddr(iph->dport());
00501
00502 char flags[NUMFLAGS+1];
00503 for (int i = 0; i < NUMFLAGS; i++)
00504 flags[i] = '-';
00505 flags[NUMFLAGS] = 0;
00506
00507 hdr_flags* hf = hdr_flags::access(p);
00508 flags[0] = hf->ecn_ ? 'C' : '-';
00509 flags[1] = hf->pri_ ? 'P' : '-';
00510 flags[2] = '-';
00511 flags[3] = hf->cong_action_ ? 'A' : '-';
00512 flags[4] = hf->ecn_to_echo_ ? 'E' : '-';
00513 flags[5] = hf->fs_ ? 'F' : '-';
00514 flags[6] = hf->ecn_capable_ ? 'N' : '-';
00515
00516 #ifdef notdef
00517 flags[1] = (iph->flags() & PF_PRI) ? 'P' : '-';
00518 flags[2] = (iph->flags() & PF_USR1) ? '1' : '-';
00519 flags[3] = (iph->flags() & PF_USR2) ? '2' : '-';
00520 flags[5] = 0;
00521 #endif
00522
00523 sprintf(pt_->nbuffer(),
00524 "%c -t %g -s %d -d %d -p %s -e %d -c %d -i %d -a %d -x {%s.%s %s.%s %d %s %s}",
00525 'h',
00526 Scheduler::instance().clock(),
00527 src_,
00528 dst_,
00529 name,
00530 th->size(),
00531 iph->flowid(),
00532 th->uid(),
00533 iph->flowid(),
00534 src_nodeaddr,
00535 src_portaddr,
00536 dst_nodeaddr,
00537 dst_portaddr,
00538 -1, flags, sname);
00539 pt_->namdump();
00540 delete [] src_nodeaddr;
00541 delete [] src_portaddr;
00542 delete [] dst_nodeaddr;
00543 delete [] dst_portaddr;
00544 }
00545
00546
00547 if (target_ == 0)
00548 Packet::free(p);
00549 else
00550 send(p, h);
00551 }