#include <TCPDump.h>
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 |
TCPDumper::TCPDumper | ( | std::ostream & | o | ) |
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 }
int32 TCPDumper::seq [protected] |
std::ostream* TCPDumper::outp [protected] |
Referenced by dump(), dumpIPv6(), sctpDump(), tcpDump(), TCPDumper(), and udpDump().
FILE* TCPDumper::dumpfile |
Referenced by TCPDump::finish(), TCPDump::handleMessage(), and TCPDump::initialize().