Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members | File Members

sattrace.cc

Go to the documentation of this file.
00001 /* -*-  Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
00002 /*
00003  * Copyright (c) 1999 Regents of the University of California.
00004  * All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions
00008  * are met:
00009  * 1. Redistributions of source code must retain the above copyright
00010  *    notice, this list of conditions and the following disclaimer.
00011  * 2. Redistributions in binary form must reproduce the above copyright
00012  *    notice, this list of conditions and the following disclaimer in the
00013  *    documentation and/or other materials provided with the distribution.
00014  * 3. All advertising materials mentioning features or use of this software
00015  *    must display the following acknowledgement:
00016  *      This product includes software developed by the MASH Research
00017  *      Group at the University of California Berkeley.
00018  * 4. Neither the name of the University nor of the Research Group may be
00019  *    used to endorse or promote products derived from this software without
00020  *    specific prior written permission.
00021  *
00022  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00023  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00024  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00025  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00026  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00027  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00028  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00029  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00031  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00032  * SUCH DAMAGE.
00033  *
00034  * Contributed by Tom Henderson, UCB Daedalus Research Group, June 1999
00035  * speedup hack from Lloyd Wood, 11 October 1999 */
00036 
00037 #ifndef lint
00038 static const char rcsid[] =
00039     "@(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/satellite/sattrace.cc,v 1.12 2002/03/22 23:49:03 buchheim 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 "rtp.h"
00048 #include "srm.h"
00049 #include "flags.h"
00050 #include "address.h"
00051 #include "trace.h"
00052 #include "sattrace.h"
00053 #include "satposition.h"
00054 #include "satnode.h"
00055 
00056 class SatTraceClass : public TclClass {
00057 public:
00058         SatTraceClass() : TclClass("Trace/Sat") { }
00059         TclObject* create(int argc, const char*const* argv) {
00060                 if (argc >= 5) {
00061                         return (new SatTrace(*argv[4]));
00062                 }
00063                 return 0;
00064         }
00065 } sat_trace_class;
00066 
00067 // XXX this should be moved from trace.cc to trace.h 
00068 char* srm_names_[] = {
00069         SRM_NAMES
00070 };
00071 
00072 void SatTrace::format(int tt, int s, int d, Packet* p)
00073 {
00074         hdr_cmn *th = hdr_cmn::access(p);
00075         hdr_ip *iph = hdr_ip::access(p);
00076         hdr_tcp *tcph = hdr_tcp::access(p);
00077         hdr_rtp *rh = hdr_rtp::access(p);
00078         hdr_srm *sh = hdr_srm::access(p); 
00079 
00080         const char* sname = "null";
00081         int lasth, nexth, snadd;
00082         Node* n;
00083 
00084         packet_t t = th->ptype();
00085         const char* name = packet_info.name(t);
00086 
00087         /* SRM-specific */
00088         if (strcmp(name,"SRM") == 0 || strcmp(name,"cbr") == 0 || strcmp(name,"udp") == 0) {
00089             if ( sh->type() < 5 && sh->type() > 0 ) {
00090                 sname = srm_names_[sh->type()];
00091             }
00092         }
00093 
00094         if (name == 0)
00095                 abort();
00096 
00097         int seqno;
00098         /* UDP's now have seqno's too */
00099         if (t == PT_RTP || t == PT_CBR || t == PT_UDP || t == PT_EXP ||
00100             t == PT_PARETO)
00101                 seqno = rh->seqno();
00102         else if (t == PT_TCP || t == PT_ACK || t == PT_HTTP || t == PT_FTP ||
00103             t == PT_TELNET)
00104                 seqno = tcph->seqno();
00105         else
00106                 seqno = -1;
00107         /* 
00108          * When new flags are added, make sure to change NUMFLAGS
00109          * in trace.h
00110          */
00111         char flags[NUMFLAGS+1];
00112         for (int i = 0; i < NUMFLAGS; i++)
00113                 flags[i] = '-';
00114         flags[NUMFLAGS] = 0;
00115 
00116         hdr_flags* hf = hdr_flags::access(p);
00117         flags[0] = hf->ecn_ ? 'C' : '-';          // Ecn Echo
00118         flags[1] = hf->pri_ ? 'P' : '-'; 
00119         flags[2] = '-';
00120         flags[3] = hf->cong_action_ ? 'A' : '-';   // Congestion Action
00121         flags[4] = hf->ecn_to_echo_ ? 'E' : '-';   // Congestion Experienced
00122         flags[5] = hf->fs_ ? 'F' : '-';
00123         flags[6] = hf->ecn_capable_ ? 'N' : '-';
00124         
00125 #ifdef notdef
00126         flags[1] = (iph->flags() & PF_PRI) ? 'P' : '-';
00127         flags[2] = (iph->flags() & PF_USR1) ? '1' : '-';
00128         flags[3] = (iph->flags() & PF_USR2) ? '2' : '-';
00129         flags[5] = 0;
00130 #endif
00131         char *src_nodeaddr = Address::instance().print_nodeaddr(iph->saddr());
00132         char *src_portaddr = Address::instance().print_portaddr(iph->sport());
00133         char *dst_nodeaddr = Address::instance().print_nodeaddr(iph->daddr());
00134         char *dst_portaddr = Address::instance().print_portaddr(iph->dport());
00135 
00136         // Find position of previous hop and next hop
00137         double s_lat = -999, s_lon = -999, d_lat = -999, d_lon = -999;
00138         n = Node::nodehead_.lh_first;
00139 // XXX what if n is not a SatNode?? Need a dynamic cast here, or make sure that
00140 // only sat tracing elements go between sat nodes.
00141         // SatNode *sn = dynamic_cast<SatNode*>(n);
00142         if (n) {
00143                 lasth = th->last_hop_;
00144                 nexth = th->next_hop_;
00145                 for (; n; n = n->nextnode() ) {
00146                         SatNode *sn = (SatNode*) n;
00147                         snadd = sn->address();
00148                         if (lasth == snadd) {
00149                                 s_lat = RAD_TO_DEG(SatGeometry::get_latitude(sn->position()->coord()));
00150                                 s_lon = RAD_TO_DEG(SatGeometry::get_longitude(sn->position()->coord()));
00151                                 if (d_lat != -999) 
00152                                         break; // Have now found both s and d
00153                         }
00154                         if (nexth == snadd) {
00155                                 d_lat = RAD_TO_DEG(SatGeometry::get_latitude(sn->position()->coord())); 
00156                                 d_lon = RAD_TO_DEG(SatGeometry::get_longitude(sn->position()->coord()));
00157                                 if (s_lat != -999) 
00158                                         break; // Have now found both s and d
00159                         }
00160                 }
00161         }
00162 
00163         if (pt_->tagged()) {
00164                 sprintf(pt_->nbuffer(), 
00165                         "%c %g -s %d -d %d -p %s -e %d -c %d -i %d -a %d -x {%s.%s %s.%s %d %s %s}",
00166                         tt,
00167                         Scheduler::instance().clock(),
00168                         s,
00169                         d,
00170                         name,
00171                         th->size(),
00172                         iph->flowid(),
00173                         th->uid(),
00174                         iph->flowid(),
00175                         src_nodeaddr,
00176                         src_portaddr,
00177                         dst_nodeaddr,
00178                         dst_portaddr,
00179                         seqno,flags,sname);
00180         } else if (!show_tcphdr_) {
00181                 sprintf(pt_->buffer(), "%c %.4f %d %d %s %d %s %d %s.%s %s.%s %d %d %.2f %.2f %.2f %.2f",
00182                         tt,
00183                         pt_->round(Scheduler::instance().clock()),
00184                         lasth,
00185                         nexth,
00186                         name,
00187                         th->size(),
00188                         flags,
00189                         iph->flowid() /* was p->class_ */,
00190                         // iph->src() >> (Address::instance().NodeShift_[1]), 
00191                         // iph->src() & (Address::instance().PortMask_), 
00192                         // iph->dst() >> (Address::instance().NodeShift_[1]), 
00193                         // iph->dst() & (Address::instance().PortMask_),
00194                         src_nodeaddr,
00195                         src_portaddr,
00196                         dst_nodeaddr,
00197                         dst_portaddr,
00198                         seqno,
00199                         th->uid(), /* was p->uid_ */
00200                         s_lat,
00201                         s_lon,
00202                         d_lat,
00203                         d_lon);
00204         } else {
00205                 sprintf(pt_->buffer(), 
00206                         "%c %.4f %d %d %s %d %s %d %s.%s %s.%s %d %d %d 0x%x %d %d %.2f %.2f %.2f %.2f",
00207                         tt,
00208                         pt_->round(Scheduler::instance().clock()),
00209                         lasth,
00210                         nexth,
00211                         name,
00212                         th->size(),
00213                         flags,
00214                         iph->flowid(), /* was p->class_ */
00215                         // iph->src() >> (Address::instance().NodeShift_[1]), 
00216                         // iph->src() & (Address::instance().PortMask_), 
00217                         // iph->dst() >> (Address::instance().NodeShift_[1]), 
00218                         // iph->dst() & (Address::instance().PortMask_),
00219                         src_nodeaddr,
00220                         src_portaddr,
00221                         dst_nodeaddr,
00222                         dst_portaddr,
00223                         seqno,
00224                         th->uid(), /* was p->uid_ */
00225                         tcph->ackno(),
00226                         tcph->flags(),
00227                         tcph->hlen(),
00228                         tcph->sa_length(),
00229                         s_lat,
00230                         s_lon,
00231                         d_lat,
00232                         d_lon);
00233         }
00234         if (pt_->namchannel() != 0)
00235                 sprintf(pt_->nbuffer(), 
00236                         "%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}",
00237                         tt,
00238                         Scheduler::instance().clock(),
00239                         s,
00240                         d,
00241                         name,
00242                         th->size(),
00243                         iph->flowid(),
00244                         th->uid(),
00245                         iph->flowid(),
00246                         src_nodeaddr,
00247                         src_portaddr,
00248                         dst_nodeaddr,
00249                         dst_portaddr,
00250                         seqno,flags,sname);
00251         delete [] src_nodeaddr;
00252         delete [] src_portaddr;
00253         delete [] dst_nodeaddr;
00254         delete [] dst_portaddr;
00255 }
00256 
00257 void SatTrace::traceonly(Packet* p)
00258 {        
00259         format(type_, src_, dst_, p);
00260         pt_->dump();
00261 }
00262 
00263 //
00264 // we need a DequeTraceClass here because a 'h' event need to go together
00265 // with the '-' event. It's possible to use a postprocessing script, but 
00266 // seems that's inconvient.
00267 //
00268 static class SatDequeTraceClass : public TclClass {
00269 public:
00270         SatDequeTraceClass() : TclClass("Trace/Sat/Deque") { }
00271         TclObject* create(int args, const char*const* argv) {
00272                 if (args >= 5)
00273                         return (new SatDequeTrace(*argv[4]));
00274                 return NULL;
00275         }
00276 } sat_dequetrace_class;
00277 
00278 
00279 void 
00280 SatDequeTrace::recv(Packet* p, Handler* h)
00281 {
00282         // write the '-' event first
00283         format(type_, src_, dst_, p);
00284         pt_->dump();
00285         pt_->namdump();
00286 
00287         if (pt_->namchannel() != 0) {
00288                 hdr_cmn *th = hdr_cmn::access(p);
00289                 hdr_ip *iph = hdr_ip::access(p);
00290                 hdr_srm *sh = hdr_srm::access(p);
00291                 const char* sname = "null";   
00292 
00293                 packet_t t = th->ptype();
00294                 const char* name = packet_info.name(t);
00295                 
00296                 if (strcmp(name,"SRM") == 0 || strcmp(name,"cbr") == 0 || strcmp(name,"udp") == 0) {
00297                     if ( sh->type() < 5 && sh->type() > 0  ) {
00298                         sname = srm_names_[sh->type()];
00299                     }
00300                 }   
00301 
00302                 char *src_nodeaddr = Address::instance().print_nodeaddr(iph->saddr());
00303                 char *src_portaddr = Address::instance().print_portaddr(iph->sport());
00304                 char *dst_nodeaddr = Address::instance().print_nodeaddr(iph->daddr());
00305                 char *dst_portaddr = Address::instance().print_portaddr(iph->dport());
00306 
00307                 char flags[NUMFLAGS+1];
00308                 for (int i = 0; i < NUMFLAGS; i++)
00309                         flags[i] = '-';
00310                 flags[NUMFLAGS] = 0;
00311 
00312                 hdr_flags* hf = hdr_flags::access(p);
00313                 flags[0] = hf->ecn_ ? 'C' : '-';          // Ecn Echo
00314                 flags[1] = hf->pri_ ? 'P' : '-'; 
00315                 flags[2] = '-';
00316                 flags[3] = hf->cong_action_ ? 'A' : '-';   // Congestion Action
00317                 flags[4] = hf->ecn_to_echo_ ? 'E' : '-';   // Congestion Experienced
00318                 flags[5] = hf->fs_ ? 'F' : '-';
00319                 flags[6] = hf->ecn_capable_ ? 'N' : '-';
00320         
00321 #ifdef notdef
00322                 flags[1] = (iph->flags() & PF_PRI) ? 'P' : '-';
00323                 flags[2] = (iph->flags() & PF_USR1) ? '1' : '-';
00324                 flags[3] = (iph->flags() & PF_USR2) ? '2' : '-';
00325                 flags[5] = 0;
00326 #endif
00327                 
00328                 sprintf(pt_->nbuffer(), 
00329                         "%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}",
00330                         'h',
00331                         Scheduler::instance().clock(),
00332                         src_,
00333                         dst_,
00334                         name,
00335                         th->size(),
00336                         iph->flowid(),
00337                         th->uid(),
00338                         iph->flowid(),
00339                         src_nodeaddr,
00340                         src_portaddr,
00341                         dst_nodeaddr,
00342                         dst_portaddr,
00343                         -1, flags, sname);
00344                 pt_->namdump();
00345                 delete [] src_nodeaddr;
00346                 delete [] src_portaddr;
00347                 delete [] dst_nodeaddr;
00348                 delete [] dst_portaddr;
00349         }
00350 
00351         /* hack: if trace object not attached to anything free packet */
00352         if (target_ == 0)
00353                 Packet::free(p);
00354         else
00355                 send(p, h);
00356 }

Generated on Tue Apr 20 12:14:31 2004 for NS2.26SourcesOriginal by doxygen 1.3.3