#include <TCPDump.h>
Public Member Functions | |
TCPDumper (std::ostream &o) | |
~TCPDumper () | |
void | setVerbosity (const int32 verbosityLevel) |
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) |
const char * | intToChunk (int32 type) |
Public Attributes | |
FILE * | dumpfile |
Protected Attributes | |
int32 | seq |
std::ostream * | outp |
Private Attributes | |
int | verbosity |
Dumps SCTP packets in tcpdump format.
Definition at line 70 of file TCPDump.h.
TCPDumper::TCPDumper | ( | std::ostream & | o | ) |
Definition at line 36 of file TCPDump.cc.
{ outp = &out; }
TCPDumper::~TCPDumper | ( | ) |
Definition at line 41 of file TCPDump.cc.
{ }
void TCPDumper::dump | ( | const char * | label, | |
const char * | msg | |||
) |
Definition at line 343 of file TCPDump.cc.
Referenced by TCPDump::finish().
{ std::ostream& out = *outp; // seq and time (not part of the tcpdump format) char buf[30]; sprintf(buf,"[%.3f%s] ", simulation.getSimTime().dbl(), label); out << buf; out << msg << "\n"; }
void TCPDumper::dumpIPv6 | ( | bool | l2r, | |
const char * | label, | |||
IPv6Datagram_Base * | dgram, | |||
const char * | comment = NULL | |||
) |
Definition at line 424 of file TCPDump.cc.
Referenced by TCPDump::handleMessage().
{ cMessage *encapmsg = dgram->getEncapsulatedMsg(); if (dynamic_cast<TCPSegment *>(encapmsg)) { // if TCP, dump as TCP tcpDump(l2r, label, (TCPSegment *)encapmsg, dgram->getSrcAddress().str(), dgram->getDestAddress().str(), comment); } else { // some other packet, dump what we can std::ostream& out = *outp; // seq and time (not part of the tcpdump format) char buf[30]; sprintf(buf,"[%.3f%s] ", SIMTIME_DBL(simTime()), label); out << buf; // packet class and name out << "? " << encapmsg->getClassName() << " \"" << encapmsg->getName() << "\"\n"; } }
const char * TCPDumper::intToChunk | ( | int32 | type | ) |
Definition at line 322 of file TCPDump.cc.
{ switch (type) { case 0: return "DATA"; case 1: return "INIT"; case 2: return "INIT_ACK"; case 3: return "SACK"; case 4: return "HEARTBEAT"; case 5: return "HEARTBEAT_ACK"; case 6: return "ABORT"; case 7: return "SHUTDOWN"; case 8: return "SHUTDOWN_ACK"; case 9: return "ERRORTYPE"; case 10: return "COOKIE_ECHO"; case 11: return "COOKIE_ACK"; case 14: return "SHUTDOWN_COMPLETE"; } return ""; }
void TCPDumper::ipDump | ( | const char * | label, | |
IPDatagram * | dgram, | |||
const char * | comment = NULL | |||
) |
Definition at line 45 of file TCPDump.cc.
Referenced by TCPDump::handleMessage().
{ if (dynamic_cast<SCTPMessage *>(dgram->getEncapsulatedMsg())) { SCTPMessage *sctpmsg = check_and_cast<SCTPMessage *>(dgram->getEncapsulatedMsg()); if (dgram->hasBitError()) sctpmsg->setBitError(true); sctpDump(label, sctpmsg, dgram->getSrcAddress().str(), dgram->getDestAddress().str(), comment); } else delete dgram; }
void TCPDumper::sctpDump | ( | const char * | label, | |
SCTPMessage * | sctpmsg, | |||
const std::string & | srcAddr, | |||
const std::string & | destAddr, | |||
const char * | comment = NULL | |||
) |
Definition at line 58 of file TCPDump.cc.
Referenced by TCPDump::handleMessage(), ipDump(), and udpDump().
{ std::ostream& out = *outp; uint32 numberOfChunks; SCTPChunk* chunk; uint8 type; // seq and time (not part of the tcpdump format) char buf[30]; sprintf(buf,"[%.3f%s] ", simulation.getSimTime().dbl(), label); out << buf; // src/dest out << srcAddr << "." << sctpmsg->getSrcPort() << " > "; out << destAddr << "." << sctpmsg->getDestPort() << ": "; if (sctpmsg->hasBitError()) { sctpmsg->setChecksumOk(false); } numberOfChunks = sctpmsg->getChunksArraySize(); out << "numberOfChunks="<<numberOfChunks<<" VTag="<<sctpmsg->getTag()<<"\n"; if (sctpmsg->hasBitError()) out << "Packet has bit error!!\n"; for (uint32 i=0; i<numberOfChunks; i++) { chunk = (SCTPChunk*)sctpmsg->getChunks(i); type = chunk->getChunkType(); switch (type) { case INIT: out << "INIT "; break; case INIT_ACK: out << "INIT_ACK "; break; case COOKIE_ECHO: out << "COOKIE_ECHO "; break; case COOKIE_ACK: out << "COOKIE_ACK "; break; case DATA: out << "DATA "; break; case SACK: out << "SACK "; break; case HEARTBEAT: out << "HEARTBEAT "; break; case HEARTBEAT_ACK: out << "HEARTBEAT_ACK "; break; case ABORT: out << "ABORT "; break; case SHUTDOWN: out << "SHUTDOWN "; break; case SHUTDOWN_ACK: out << "SHUTDOWN_ACK "; break; case SHUTDOWN_COMPLETE: out << "SHUTDOWN_COMPLETE "; break; case ERRORTYPE: out << "ERROR"; break; } } if (verbosity >= 1) { out << endl; for (uint32 i=0; i<numberOfChunks; i++) { chunk = (SCTPChunk*)sctpmsg->getChunks(i); type = chunk->getChunkType(); sprintf(buf, " %3u: ", i + 1); out << buf; switch (type) { case INIT: { SCTPInitChunk* initChunk; initChunk = check_and_cast<SCTPInitChunk *>(chunk); out << "INIT[InitiateTag="; out << initChunk->getInitTag(); out << "; a_rwnd="; out << initChunk->getA_rwnd(); out << "; OS="; out << initChunk->getNoOutStreams(); out << "; IS="; out << initChunk->getNoInStreams(); out << "; InitialTSN="; out << initChunk->getInitTSN(); if (initChunk->getAddressesArraySize() > 0) { out <<"; Addresses="; for (uint32 i = 0; i < initChunk->getAddressesArraySize(); i++) { if (i > 0) out << ","; if (initChunk->getAddresses(i).isIPv6()) out << initChunk->getAddresses(i).str(); else out << initChunk->getAddresses(i); } } out <<"]"; break; } case INIT_ACK: { SCTPInitAckChunk* initackChunk; initackChunk = check_and_cast<SCTPInitAckChunk *>(chunk); out << "INIT_ACK[InitiateTag="; out << initackChunk->getInitTag(); out << "; a_rwnd="; out << initackChunk->getA_rwnd(); out << "; OS="; out << initackChunk->getNoOutStreams(); out << "; IS="; out << initackChunk->getNoInStreams(); out << "; InitialTSN="; out << initackChunk->getInitTSN(); out << "; CookieLength="; out << initackChunk->getCookieArraySize(); if (initackChunk->getAddressesArraySize() > 0) { out <<"; Addresses="; for (uint32 i = 0; i < initackChunk->getAddressesArraySize(); i++) { if (i > 0) out << ","; out << initackChunk->getAddresses(i); } } out <<"]"; break; } case COOKIE_ECHO: out << "COOKIE_ECHO[CookieLength="; out << chunk->getBitLength()/8 - 4; out <<"]"; break; case COOKIE_ACK: out << "COOKIE_ACK "; break; case DATA: { SCTPDataChunk* dataChunk; dataChunk = check_and_cast<SCTPDataChunk *>(chunk); out << "DATA[TSN="; out << dataChunk->getTsn(); out << "; SID="; out << dataChunk->getSid(); out << "; SSN="; out << dataChunk->getSsn(); out << "; PPID="; out << dataChunk->getPpid(); out << "; PayloadLength="; out << dataChunk->getBitLength()/8 - 16; out <<"]"; break; } case SACK: { SCTPSackChunk* sackChunk; sackChunk = check_and_cast<SCTPSackChunk *>(chunk); out << "SACK[CumTSNAck="; out << sackChunk->getCumTsnAck(); out << "; a_rwnd="; out << sackChunk->getA_rwnd(); if (sackChunk->getGapStartArraySize() > 0) { out <<"; Gaps="; for (uint32 i = 0; i < sackChunk->getGapStartArraySize(); i++) { if (i > 0) out << ", "; out << sackChunk->getGapStart(i) << "-" << sackChunk->getGapStop(i); } } if (sackChunk->getDupTsnsArraySize() > 0) { out <<"; Dups="; for (uint32 i = 0; i < sackChunk->getDupTsnsArraySize(); i++) { if (i > 0) out << ", "; out << sackChunk->getDupTsns(i); } } out <<"]"; break; } case HEARTBEAT: SCTPHeartbeatChunk* heartbeatChunk; heartbeatChunk = check_and_cast<SCTPHeartbeatChunk *>(chunk); out << "HEARTBEAT[InfoLength="; out << chunk->getBitLength()/8 - 4; out << "; time="; out << heartbeatChunk->getTimeField(); out <<"]"; break; case HEARTBEAT_ACK: out << "HEARTBEAT_ACK[InfoLength="; out << chunk->getBitLength()/8 - 4; out <<"]"; break; case ABORT: SCTPAbortChunk* abortChunk; abortChunk = check_and_cast<SCTPAbortChunk *>(chunk); out << "ABORT[T-Bit="; out << abortChunk->getT_Bit(); out << "]"; break; case SHUTDOWN: SCTPShutdownChunk* shutdown; shutdown = check_and_cast<SCTPShutdownChunk *>(chunk); out << "SHUTDOWN[CumTSNAck="; out << shutdown->getCumTsnAck(); out << "]"; break; case SHUTDOWN_ACK: out << "SHUTDOWN_ACK "; break; case SHUTDOWN_COMPLETE: out << "SHUTDOWN_COMPLETE "; break; case ERRORTYPE: { SCTPErrorChunk* errorChunk; errorChunk = check_and_cast<SCTPErrorChunk*>(chunk); uint32 numberOfParameters = errorChunk->getParametersArraySize(); uint32 parameterType; for (uint32 i=0; i<numberOfParameters; i++) { SCTPParameter* param = (SCTPParameter*)errorChunk->getParameters(i); parameterType = param->getParameterType(); } break; } } out << endl; } } // comment if (comment) out << "# " << comment; out << endl; }
void TCPDumper::setVerbosity | ( | const int32 | verbosityLevel | ) | [inline] |
Definition at line 78 of file TCPDump.h.
Referenced by TCPDump::initialize().
{ verbosity = verbosityLevel; }
void TCPDumper::tcpDump | ( | bool | l2r, | |
const char * | label, | |||
IPDatagram * | dgram, | |||
const char * | comment = NULL | |||
) |
Definition at line 400 of file TCPDump.cc.
Referenced by dumpIPv6(), and TCPDump::handleMessage().
{ cMessage *encapmsg = dgram->getEncapsulatedMsg(); if (dynamic_cast<TCPSegment *>(encapmsg)) { // if TCP, dump as TCP tcpDump(l2r, label, (TCPSegment *)encapmsg, dgram->getSrcAddress().str(), dgram->getDestAddress().str(), comment); } else { // some other packet, dump what we can std::ostream& out = *outp; // seq and time (not part of the tcpdump format) char buf[30]; sprintf(buf,"[%.3f%s] ", SIMTIME_DBL(simTime()), label); out << buf; // packet class and name out << "? " << encapmsg->getClassName() << " \"" << encapmsg->getName() << "\"\n"; } }
void TCPDumper::tcpDump | ( | bool | l2r, | |
const char * | label, | |||
TCPSegment * | tcpseg, | |||
const std::string & | srcAddr, | |||
const std::string & | destAddr, | |||
const char * | comment = NULL | |||
) |
Definition at line 447 of file TCPDump.cc.
{ std::ostream& out = *outp; // seq and time (not part of the tcpdump format) char buf[30]; sprintf(buf,"[%.3f%s] ", SIMTIME_DBL(simTime()), label); out << buf; // src/dest ports if (l2r) { out << srcAddr << "." << tcpseg->getSrcPort() << " > "; out << destAddr << "." << tcpseg->getDestPort() << ": "; } else { out << destAddr << "." << tcpseg->getDestPort() << " < "; out << srcAddr << "." << tcpseg->getSrcPort() << ": "; } // flags bool flags = false; if (tcpseg->getUrgBit()) {flags=true; out << "U ";} if (tcpseg->getAckBit()) {flags=true; out << "A ";} if (tcpseg->getPshBit()) {flags=true; out << "P ";} if (tcpseg->getRstBit()) {flags=true; out << "R ";} if (tcpseg->getSynBit()) {flags=true; out << "S ";} if (tcpseg->getFinBit()) {flags=true; out << "F ";} if (!flags) {out << ". ";} // data-seqno if (tcpseg->getPayloadLength()>0 || tcpseg->getSynBit()) { out << tcpseg->getSequenceNo() << ":" << tcpseg->getSequenceNo()+tcpseg->getPayloadLength(); out << "(" << tcpseg->getPayloadLength() << ") "; } // ack if (tcpseg->getAckBit()) out << "ack " << tcpseg->getAckNo() << " "; // window out << "win " << tcpseg->getWindow() << " "; // urgent if (tcpseg->getUrgBit()) out << "urg " << tcpseg->getUrgentPointer() << " "; // options present? if (tcpseg->getHeaderLength() > 20) { std::string direction = "sent"; if (l2r) // change direction {direction = "received";} unsigned short numOptions = tcpseg->getOptionsArraySize(); out << "\nTCP Header Option(s) " << direction << ":\n"; for (int i=0; i<numOptions; i++) { TCPOption option = tcpseg->getOptions(i); unsigned short kind = option.getKind(); unsigned short length = option.getLength(); out << (i+1) << ". option kind=" << kind << " length=" << length << "\n"; } } // comment if (comment) out << "# " << comment; out << endl; }
void TCPDumper::udpDump | ( | bool | l2r, | |
const char * | label, | |||
IPDatagram * | dgram, | |||
const char * | comment | |||
) |
Definition at line 365 of file TCPDump.cc.
Referenced by TCPDump::handleMessage().
{ cMessage *encapmsg = dgram->getEncapsulatedMsg(); if (dynamic_cast<UDPPacket *>(encapmsg)) { std::ostream& out = *outp; // seq and time (not part of the tcpdump format) char buf[30]; sprintf(buf,"[%.3f%s] ", simulation.getSimTime().dbl(), label); out << buf; UDPPacket* udppkt = check_and_cast<UDPPacket*>(encapmsg); // src/dest if (l2r) { out << dgram->getSrcAddress().str() << "." << udppkt->getSourcePort() << " > "; out << dgram->getDestAddress().str() << "." << udppkt->getDestinationPort() << ": "; } else { out << dgram->getDestAddress().str() << "." << udppkt->getDestinationPort() << " < "; out << dgram->getSrcAddress().str() << "." << udppkt->getSourcePort() << ": "; } //out << endl; out << "UDP: Payload length=" << udppkt->getByteLength()-8 << endl; if (udppkt->getSourcePort()==9899 || udppkt->getDestinationPort() == 9899) { if (dynamic_cast<SCTPMessage *>(udppkt->getEncapsulatedMsg())) sctpDump("", (SCTPMessage *)(udppkt->getEncapsulatedMsg()), std::string(l2r?"A":"B"),std::string(l2r?"B":"A")); } } }
FILE* TCPDumper::dumpfile |
Definition at line 90 of file TCPDump.h.
Referenced by TCPDump::finish(), TCPDump::handleMessage(), and TCPDump::initialize().
std::ostream* TCPDumper::outp [protected] |
Definition at line 74 of file TCPDump.h.
Referenced by dump(), dumpIPv6(), sctpDump(), tcpDump(), TCPDumper(), and udpDump().
int32 TCPDumper::seq [protected] |
int TCPDumper::verbosity [private] |
Definition at line 92 of file TCPDump.h.
Referenced by sctpDump(), and setVerbosity().