TCPDumper Class Reference

#include <TCPDump.h>

List of all members.


Detailed Description

Dumps SCTP packets in tcpdump format.

Public Member Functions

 TCPDumper (std::ostream &o)
 ~TCPDumper ()
void ipDump (const char *label, IPDatagram *dgram, const char *comment=NULL)
void sctpDump (const char *label, SCTPMessage *sctpmsg, const std::string &srcAddr, const std::string &destAddr, const char *comment=NULL)
void dump (const char *label, const char *msg)
void tcpDump (bool l2r, const char *label, IPDatagram *dgram, const char *comment=NULL)
void tcpDump (bool l2r, const char *label, TCPSegment *tcpseg, const std::string &srcAddr, const std::string &destAddr, const char *comment=NULL)
void dumpIPv6 (bool l2r, const char *label, IPv6Datagram_Base *dgram, const char *comment=NULL)
void udpDump (bool l2r, const char *label, IPDatagram *dgram, const char *comment)
char * intToChunk (int32 type)

Public Attributes

FILE * dumpfile

Protected Attributes

int32 seq
std::ostream * outp

Constructor & Destructor Documentation

TCPDumper::TCPDumper ( std::ostream &  o  ) 

00033 {
00034     outp = &out;
00035 }

TCPDumper::~TCPDumper (  ) 

00038 {
00039 }


Member Function Documentation

void TCPDumper::ipDump ( const char *  label,
IPDatagram *  dgram,
const char *  comment = NULL 
)

Referenced by TCPDump::handleMessage().

00042 {
00043     if (dynamic_cast<SCTPMessage *>(dgram->getEncapsulatedMsg()))
00044     {
00045         SCTPMessage *sctpmsg = check_and_cast<SCTPMessage *>(dgram->getEncapsulatedMsg());
00046         if (dgram->hasBitError())
00047             sctpmsg->setBitError(true);
00048         sctpDump(label, sctpmsg, dgram->getSrcAddress().str(), dgram->getDestAddress().str(), comment);
00049     }
00050     else
00051         delete dgram;
00052 }

void TCPDumper::sctpDump ( const char *  label,
SCTPMessage sctpmsg,
const std::string &  srcAddr,
const std::string &  destAddr,
const char *  comment = NULL 
)

Referenced by TCPDump::handleMessage(), and ipDump().

00055 {
00056     std::ostream& out = *outp;
00057     uint32 numberOfChunks;
00058     SCTPChunk* chunk;
00059     uint8 type;
00060     // seq and time (not part of the tcpdump format)
00061     char buf[30];
00062     sprintf(buf,"[%.3f%s] ", simulation.getSimTime().dbl(), label);
00063     out << buf;
00064 
00065     // src/dest
00066     out << srcAddr  << "." << sctpmsg->getSrcPort()  << " > ";
00067 
00068     out << destAddr << "." << sctpmsg->getDestPort() << ": ";
00069     if (sctpmsg->hasBitError())
00070     {
00071         sctpmsg->setChecksumOk(false);
00072     }
00073     numberOfChunks = sctpmsg->getChunksArraySize();
00074     out << "numberOfChunks="<<numberOfChunks<<" VTag="<<sctpmsg->getTag()<<"\n";
00075     if (sctpmsg->hasBitError())
00076         out << "Packet has bit error!!\n";
00077     for (uint32 i=0; i<numberOfChunks; i++)
00078     {
00079         chunk = (SCTPChunk*)sctpmsg->getChunks(i);
00080         type  = chunk->getChunkType();
00081         switch (type)
00082         {
00083             case INIT:
00084                 out << "INIT ";
00085                 break;
00086             case INIT_ACK:
00087                 out << "INIT_ACK ";
00088                 break;
00089             case COOKIE_ECHO:
00090                 out << "COOKIE_ECHO ";
00091                 break;
00092             case COOKIE_ACK:
00093                 out << "COOKIE_ACK ";
00094                 break;
00095             case DATA:
00096                 out << "DATA ";
00097                 break;
00098             case SACK:
00099                 out << "SACK ";
00100                 break;
00101             case HEARTBEAT:
00102                 out << "HEARTBEAT ";
00103                 break;
00104             case HEARTBEAT_ACK:
00105                 out << "HEARTBEAT_ACK ";
00106                 break;
00107             case ABORT:
00108                 out << "ABORT ";
00109                 break;
00110             case SHUTDOWN:
00111                 out << "SHUTDOWN ";
00112                 break;
00113             case SHUTDOWN_ACK:
00114                 out << "SHUTDOWN_ACK ";
00115                 break;
00116             case SHUTDOWN_COMPLETE:
00117                 out << "SHUTDOWN_COMPLETE ";
00118                 break;
00119             case ERRORTYPE:
00120                 out << "ERROR";
00121                 break;
00122 
00123         }
00124     }
00125     int32 verbose = 1;
00126 
00127     if (verbose == 1)
00128     {
00129         out << endl;
00130         for (uint32 i=0; i<numberOfChunks; i++)
00131         {
00132             chunk = (SCTPChunk*)sctpmsg->getChunks(i);
00133             type  = chunk->getChunkType();
00134 
00135             sprintf(buf,  "     %3u: ", i + 1);
00136             out << buf;
00137             switch (type)
00138             {
00139                 case INIT:
00140                 {
00141                     SCTPInitChunk* initChunk;
00142                     initChunk = check_and_cast<SCTPInitChunk *>(chunk);
00143                     out << "INIT[InitiateTag=";
00144                     out << initChunk->getInitTag();
00145                     out << "; a_rwnd=";
00146                     out << initChunk->getA_rwnd();
00147                     out << "; OS=";
00148                     out << initChunk->getNoOutStreams();
00149                     out << "; IS=";
00150                     out << initChunk->getNoInStreams();
00151                     out << "; InitialTSN=";
00152                     out << initChunk->getInitTSN();
00153                     if (initChunk->getAddressesArraySize() > 0)
00154                     {
00155                         out <<"; Addresses=";
00156                         for (uint32 i = 0; i < initChunk->getAddressesArraySize(); i++)
00157                         {
00158                             if (i > 0)
00159                                 out << ",";
00160                             if (initChunk->getAddresses(i).isIPv6())
00161                                 out << initChunk->getAddresses(i).str();
00162                             else
00163                                 out << initChunk->getAddresses(i);
00164                         }
00165                     }
00166 
00167                     out <<"]";
00168                     break;
00169                 }
00170                 case INIT_ACK:
00171                 {
00172                     SCTPInitAckChunk* initackChunk;
00173                     initackChunk = check_and_cast<SCTPInitAckChunk *>(chunk);
00174                     out << "INIT_ACK[InitiateTag=";
00175                     out << initackChunk->getInitTag();
00176                     out << "; a_rwnd=";
00177                     out << initackChunk->getA_rwnd();
00178                     out << "; OS=";
00179                     out << initackChunk->getNoOutStreams();
00180                     out << "; IS=";
00181                     out << initackChunk->getNoInStreams();
00182                     out << "; InitialTSN=";
00183                     out << initackChunk->getInitTSN();
00184                     out << "; CookieLength=";
00185                     out << initackChunk->getCookieArraySize();
00186                     if (initackChunk->getAddressesArraySize() > 0)
00187                     {
00188                         out <<"; Addresses=";
00189                         for (uint32 i = 0; i < initackChunk->getAddressesArraySize(); i++)
00190                         {
00191                             if (i > 0)
00192                                 out << ",";
00193                             out << initackChunk->getAddresses(i);
00194                         }
00195                     }
00196                     out <<"]";
00197                     break;
00198                 }
00199                 case COOKIE_ECHO:
00200                     out << "COOKIE_ECHO[CookieLength=";
00201                     out <<  chunk->getBitLength()/8 - 4;
00202                     out <<"]";
00203                     break;
00204                 case COOKIE_ACK:
00205                     out << "COOKIE_ACK ";
00206                     break;
00207                 case DATA:
00208                 {
00209                     SCTPDataChunk* dataChunk;
00210                     dataChunk = check_and_cast<SCTPDataChunk *>(chunk);
00211                     out << "DATA[TSN=";
00212                     out << dataChunk->getTsn();
00213                     out << "; SID=";
00214                     out << dataChunk->getSid();
00215                     out << "; SSN=";
00216                     out << dataChunk->getSsn();
00217                     out << "; PPID=";
00218                     out << dataChunk->getPpid();
00219                     out << "; PayloadLength=";
00220                     out << dataChunk->getBitLength()/8 - 16;
00221                     out <<"]";
00222                     break;
00223                 }
00224                 case SACK:
00225                 {
00226                     SCTPSackChunk* sackChunk;
00227                     sackChunk = check_and_cast<SCTPSackChunk *>(chunk);
00228                     out << "SACK[CumTSNAck=";
00229                     out << sackChunk->getCumTsnAck();
00230                     out << "; a_rwnd=";
00231                     out << sackChunk->getA_rwnd();
00232                     if (sackChunk->getGapStartArraySize() > 0)
00233                     {
00234                         out <<"; Gaps=";
00235                         for (uint32 i = 0; i < sackChunk->getGapStartArraySize(); i++)
00236                         {
00237                             if (i > 0)
00238                                 out << ", ";
00239                             out << sackChunk->getGapStart(i) << "-" << sackChunk->getGapStop(i);
00240                         }
00241                     }
00242                     if (sackChunk->getDupTsnsArraySize() > 0)
00243                     {
00244                         out <<"; Dups=";
00245                         for (uint32 i = 0; i < sackChunk->getDupTsnsArraySize(); i++)
00246                         {
00247                             if (i > 0)
00248                                 out << ", ";
00249                             out << sackChunk->getDupTsns(i);
00250                         }
00251                     }
00252                     out <<"]";
00253                     break;
00254                 }
00255                 case HEARTBEAT:
00256                     SCTPHeartbeatChunk* heartbeatChunk;
00257                     heartbeatChunk = check_and_cast<SCTPHeartbeatChunk *>(chunk);
00258                     out << "HEARTBEAT[InfoLength=";
00259                     out <<  chunk->getBitLength()/8 - 4;
00260                     out << "; time=";
00261                     out << heartbeatChunk->getTimeField();
00262                     out <<"]";
00263                     break;
00264                 case HEARTBEAT_ACK:
00265                     out << "HEARTBEAT_ACK[InfoLength=";
00266                     out <<  chunk->getBitLength()/8 - 4;
00267                     out <<"]";
00268                     break;
00269                 case ABORT:
00270                     SCTPAbortChunk* abortChunk;
00271                     abortChunk = check_and_cast<SCTPAbortChunk *>(chunk);
00272                     out << "ABORT[T-Bit=";
00273                     out << abortChunk->getT_Bit();
00274                     out << "]";
00275                     break;
00276                 case SHUTDOWN:
00277                     SCTPShutdownChunk* shutdown;
00278                     shutdown = check_and_cast<SCTPShutdownChunk *>(chunk);
00279                     out << "SHUTDOWN[CumTSNAck=";
00280                     out << shutdown->getCumTsnAck();
00281                     out << "]";
00282                     break;
00283                 case SHUTDOWN_ACK:
00284                     out << "SHUTDOWN_ACK ";
00285                     break;
00286                 case SHUTDOWN_COMPLETE:
00287                     out << "SHUTDOWN_COMPLETE ";
00288                     break;
00289                 case ERRORTYPE:
00290                 {
00291                     SCTPErrorChunk* errorChunk;
00292                     errorChunk = check_and_cast<SCTPErrorChunk*>(chunk);
00293                     uint32 numberOfParameters = errorChunk->getParametersArraySize();
00294                     uint32 parameterType;
00295                     for (uint32 i=0; i<numberOfParameters; i++)
00296                     {
00297                         SCTPParameter* param = (SCTPParameter*)errorChunk->getParameters(i);
00298                         parameterType  = param->getParameterType();
00299                     }
00300 
00301                     break;
00302                 }
00303 
00304             }
00305             out << endl;
00306         }
00307     }
00308     // comment
00309     if (comment)
00310         out << "# " << comment;
00311 
00312     out << endl;
00313 }

void TCPDumper::dump ( const char *  label,
const char *  msg 
)

Referenced by TCPDump::finish().

00344 {
00345     std::ostream& out = *outp;
00346 
00347     // seq and time (not part of the tcpdump format)
00348     char buf[30];
00349     sprintf(buf,"[%.3f%s] ", simulation.getSimTime().dbl(), label);
00350     out << buf;
00351 
00352     out << msg << "\n";
00353 }

void TCPDumper::tcpDump ( bool  l2r,
const char *  label,
IPDatagram *  dgram,
const char *  comment = NULL 
)

Referenced by dumpIPv6(), and TCPDump::handleMessage().

00401 {
00402     cMessage *encapmsg = dgram->getEncapsulatedMsg();
00403     if (dynamic_cast<TCPSegment *>(encapmsg))
00404     {
00405         // if TCP, dump as TCP
00406         tcpDump(l2r, label, (TCPSegment *)encapmsg, dgram->getSrcAddress().str(), dgram->getDestAddress().str(), comment);
00407     }
00408     else
00409     {
00410         // some other packet, dump what we can
00411         std::ostream& out = *outp;
00412 
00413         // seq and time (not part of the tcpdump format)
00414         char buf[30];
00415         sprintf(buf,"[%.3f%s] ", SIMTIME_DBL(simTime()), label);
00416         out << buf;
00417 
00418         // packet class and name
00419         out << "? " << encapmsg->getClassName() << " \"" << encapmsg->getName() << "\"\n";
00420     }
00421 }

void TCPDumper::tcpDump ( bool  l2r,
const char *  label,
TCPSegment tcpseg,
const std::string &  srcAddr,
const std::string &  destAddr,
const char *  comment = NULL 
)

00449 {
00450     std::ostream& out = *outp;
00451 
00452     // seq and time (not part of the tcpdump format)
00453     char buf[30];
00454     sprintf(buf,"[%.3f%s] ", SIMTIME_DBL(simTime()), label);
00455     out << buf;
00456 
00457     // src/dest
00458     if (l2r)
00459     {
00460         out << srcAddr << "." << tcpseg->getSrcPort() << " > ";
00461         out << destAddr << "." << tcpseg->getDestPort() << ": ";
00462     }
00463     else
00464     {
00465         out << destAddr << "." << tcpseg->getDestPort() << " < ";
00466         out << srcAddr << "." << tcpseg->getSrcPort() << ": ";
00467     }
00468 
00469     // flags
00470     bool flags = false;
00471     if (tcpseg->getSynBit()) {flags=true; out << "S";}
00472     if (tcpseg->getFinBit()) {flags=true; out << "F";}
00473     if (tcpseg->getPshBit()) {flags=true; out << "P";}
00474     if (tcpseg->getRstBit()) {flags=true; out << "R";}
00475     if (!flags) {out << ".";}
00476     out << " ";
00477 
00478     // data-seqno
00479     if (tcpseg->getPayloadLength()>0 || tcpseg->getSynBit())
00480     {
00481         out << tcpseg->getSequenceNo() << ":" << tcpseg->getSequenceNo()+tcpseg->getPayloadLength();
00482         out << "(" << tcpseg->getPayloadLength() << ") ";
00483     }
00484 
00485     // ack
00486     if (tcpseg->getAckBit())
00487         out << "ack " << tcpseg->getAckNo() << " ";
00488 
00489     // window
00490     out << "win " << tcpseg->getWindow() << " ";
00491 
00492     // urgent
00493     if (tcpseg->getUrgBit())
00494         out << "urg " << tcpseg->getUrgentPointer() << " ";
00495 
00496     // options (not supported by TCPSegment yet)
00497 
00498     // comment
00499     if (comment)
00500         out << "# " << comment;
00501 
00502     out << endl;
00503 }

void TCPDumper::dumpIPv6 ( bool  l2r,
const char *  label,
IPv6Datagram_Base *  dgram,
const char *  comment = NULL 
)

Referenced by TCPDump::handleMessage().

00425 {
00426     cMessage *encapmsg = dgram->getEncapsulatedMsg();
00427     if (dynamic_cast<TCPSegment *>(encapmsg))
00428     {
00429         // if TCP, dump as TCP
00430         tcpDump(l2r, label, (TCPSegment *)encapmsg, dgram->getSrcAddress().str(), dgram->getDestAddress().str(), comment);
00431     }
00432     else
00433     {
00434         // some other packet, dump what we can
00435         std::ostream& out = *outp;
00436 
00437         // seq and time (not part of the tcpdump format)
00438         char buf[30];
00439         sprintf(buf,"[%.3f%s] ", SIMTIME_DBL(simTime()), label);
00440         out << buf;
00441 
00442         // packet class and name
00443         out << "? " << encapmsg->getClassName() << " \"" << encapmsg->getName() << "\"\n";
00444     }
00445 }

void TCPDumper::udpDump ( bool  l2r,
const char *  label,
IPDatagram *  dgram,
const char *  comment 
)

Referenced by TCPDump::handleMessage().

00371 {
00372     cMessage *encapmsg = dgram->getEncapsulatedMsg();
00373     if (dynamic_cast<UDPPacket *>(encapmsg))
00374     {
00375         std::ostream& out = *outp;
00376 
00377     // seq and time (not part of the tcpdump format)
00378     char buf[30];
00379     sprintf(buf,"[%.3f%s] ", simulation.getSimTime().dbl(), label);
00380     out << buf;
00381     UDPPacket* udppkt = check_and_cast<UDPPacket*>(encapmsg);
00382 
00383     // src/dest
00384     if (l2r)
00385     {
00386         out << dgram->getSrcAddress().str() << "." << udppkt->getSourcePort() << " > ";
00387         out << dgram->getDestAddress().str() << "." << udppkt->getDestinationPort() << ": ";
00388     }
00389     else
00390     {
00391         out << dgram->getDestAddress().str() << "." << udppkt->getDestinationPort() << " < ";
00392         out << dgram->getSrcAddress().str() << "." << udppkt->getSourcePort() << ": ";
00393     }
00394 
00395      out << endl;
00396     out << "UDP: Payload length=" << udppkt->getByteLength()-8 << endl;
00397     }
00398 }

char * TCPDumper::intToChunk ( int32  type  ) 

00323 {
00324     switch (type)
00325     {
00326         case 0: return "DATA";
00327         case 1: return "INIT";
00328         case 2: return "INIT_ACK";
00329         case 3: return "SACK";
00330         case 4: return "HEARTBEAT";
00331         case 5: return "HEARTBEAT_ACK";
00332         case 6: return "ABORT";
00333         case 7: return "SHUTDOWN";
00334         case 8: return "SHUTDOWN_ACK";
00335         case 9: return "ERRORTYPE";
00336         case 10: return "COOKIE_ECHO";
00337         case 11: return "COOKIE_ACK";
00338         case 14: return "SHUTDOWN_COMPLETE";
00339     }
00340     return "";
00341 }


Member Data Documentation

int32 TCPDumper::seq [protected]

std::ostream* TCPDumper::outp [protected]


The documentation for this class was generated from the following files:

Generated on Fri Mar 20 18:51:22 2009 for INET Framework for OMNeT++/OMNEST by  doxygen 1.5.5