00001 #include "headers.h"
00002
00013
00017 NpPacket::NpPacket()
00018 {
00019 m_versionNumber = VERSION_NUMBER;
00020 m_controlType = NpPacket::Ping;
00021 m_length = 0;
00022 m_vcn = 0;
00023 m_data = NULL;
00024 m_rawData = NULL;
00025 m_headerLength = NP_HEADER_LENGTH;
00026 }
00027
00028
00034 NpPacket::NpPacket(NpType type, unsigned int vcn) {
00035 m_versionNumber = VERSION_NUMBER;
00036 m_controlType = type;
00037 m_vcn = vcn;
00038
00039 m_length = 0;
00040 m_data = NULL;
00041 m_rawData = NULL;
00042 m_headerLength = NP_HEADER_LENGTH;
00043 }
00044
00045
00049 NpPacket::NpPacket(TpPacket* data, unsigned int vcn)
00050 {
00051 m_versionNumber = VERSION_NUMBER;
00052 m_controlType = Data;
00053 m_length = data->getTpLength();
00054 m_vcn = vcn;
00055 m_data = data->getTpData();
00056 m_rawData = m_data - NP_HEADER_LENGTH;
00057 m_headerLength = NP_HEADER_LENGTH;
00058 }
00059
00060
00065 NpPacket::NpPacket(unsigned char* rawData)
00066 {
00067 m_versionNumber = (int)((rawData[VersionNumberOffset] & 0xF0) >> 4);
00068 m_controlType = (NpType)(rawData[PacketTypeOffset] & 0x0F);
00069
00070 memcpy(&m_length, &rawData[LengthOffset], S_USHORT);
00071 m_length = ntohs(m_length);
00072
00073 memcpy(&m_vcn, &rawData[VcnOffset], S_UINT);
00074 m_vcn = ntohl(m_vcn);
00075
00076 if (isControlPacket()) {
00077 m_data = NULL;
00078 }
00079 else {
00080 m_data = rawData + NP_HEADER_LENGTH;
00081 }
00082 m_rawData = rawData;
00083 m_headerLength = NP_HEADER_LENGTH;
00084 }
00085
00086
00092 NpPacket*
00093 NpPacket::createPacket(NpType packetType) {
00094 NpPacket* npPacket;
00095
00096 switch(packetType)
00097 {
00098 case Connect:
00099 npPacket = new ConnectionPacket();
00100 break;
00101 case Fin:
00102 npPacket = new FinPacket();
00103 break;
00104 case Discovery:
00105 npPacket = new DiscoveryPacket();
00106 break;
00107 case ImHere:
00108 npPacket = new ImHerePacket();
00109 break;
00110 default:
00111 npPacket = new NpPacket(packetType, 0);
00112 break;
00113 }
00114 MEMCHECK(npPacket);
00115 return npPacket;
00116 }
00117
00118
00128 NpPacket*
00129 NpPacket::decode(unsigned char* rawData, NpType packetType)
00130 {
00131 NpPacket* npPacket;
00132
00133 switch(packetType)
00134 {
00135 case Connect:
00136 npPacket = new ConnectionPacket(rawData);
00137 break;
00138 case Fin:
00139 npPacket = new FinPacket(rawData);
00140 break;
00141 case Discovery:
00142 npPacket = new DiscoveryPacket(rawData);
00143 break;
00144 case ImHere:
00145 npPacket = new ImHerePacket(rawData);
00146 break;
00147 default:
00148 npPacket = new NpPacket(rawData);
00149 break;
00150 }
00151 MEMCHECK(npPacket);
00152 debug(DEBUG_PACKET, "Decoded %s packet", npPacket->getControlTypeString());
00153 return npPacket;
00154 }
00155
00156
00163 int
00164 NpPacket::parseMiniHeader(unsigned char* rawData, unsigned int* rawLength,
00165 int* versionNumber, NpType* packetType) {
00166
00167
00168 *versionNumber = (int)((rawData[VersionNumberOffset] & 0xF0) >> 4);
00169 if (*versionNumber != VERSION_NUMBER) {
00170 debug(DEBUG_PACKET, "Version number not supported: %d", *versionNumber);
00171 return -1;
00172 }
00173
00174
00175 *packetType = (NpType)(rawData[PacketTypeOffset] & 0x0F);
00176 if ((*packetType < Data) || (*packetType > Pong)) {
00177 debug(DEBUG_PACKET, "Invalid packet type: %d", *packetType);
00178 return -1;
00179 }
00180
00181
00182 int headerLength = NpPacket::getHeaderLength(*packetType);
00183
00184
00185 memcpy(rawLength, &rawData[LengthOffset], S_USHORT);
00186 *rawLength = ntohs(*rawLength) + headerLength;
00187
00188
00189 if (*rawLength > (unsigned int)MAX_PACKET_LENGTH) {
00190 debug(DEBUG_PACKET, "packet length exceeds max: %d > %d", *rawLength, MAX_PACKET_LENGTH);
00191 return -1;
00192 }
00193
00194 return *rawLength;
00195 }
00196
00197
00198 NpPacket::~NpPacket()
00199 {
00200 if (m_controlType != NpPacket::Data)
00201 {
00202 if (m_rawData != NULL) {
00203 delete [] m_rawData;
00204 m_rawData = NULL;
00205 }
00206 }
00207 }
00208
00209
00210 unsigned int
00211 NpPacket::getVcn() {
00212 return m_vcn;
00213 }
00214
00215
00216 void
00217 NpPacket::setVcn(unsigned int vcn) {
00218 m_vcn = vcn;
00219 }
00220
00221
00222 void
00223 NpPacket::setPacketType(NpType type) {
00224 this->m_controlType = type;
00225 }
00226
00227
00228 unsigned char*
00229 NpPacket::getData()
00230 {
00231 return m_data;
00232 }
00233
00234
00235 unsigned int
00236 NpPacket::getDataLength() const {
00237 return (int)m_length;
00238 }
00239
00240
00247 unsigned char*
00248 NpPacket::getRawData()
00249 {
00250
00251
00252
00253 if (!m_rawData) {
00254 m_rawData = new unsigned char[m_length + m_headerLength];
00255 }
00256 MEMCHECK(m_rawData);
00257
00258
00259 m_rawData[VersionNumberOffset] = (unsigned char)(VERSION_NUMBER << 4);
00260
00261
00262 m_rawData[PacketTypeOffset] = (unsigned char)(m_rawData[PacketTypeOffset] | (m_controlType & 0x0F));
00263
00264
00265 unsigned short tmpUshort;
00266 tmpUshort = (unsigned short)(htons(m_length));
00267 memcpy(&m_rawData[LengthOffset], &tmpUshort, S_USHORT);
00268
00269
00270 unsigned int tmpUint;
00271 tmpUint = htonl(m_vcn);
00272 memcpy(&m_rawData[VcnOffset], &tmpUint, S_UINT);
00273
00274 return m_rawData;
00275 }
00276
00277
00281 unsigned int
00282 NpPacket::getRawLength() const
00283 {
00284 return m_length + m_headerLength;
00285 }
00286
00287
00291 NpPacket::NpType
00292 NpPacket::getPacketType() const
00293 {
00294 return m_controlType;
00295 }
00296
00297
00301 bool
00302 NpPacket::isControlPacket() const
00303 {
00304 return m_controlType != Data;
00305 }
00306
00307
00311 unsigned int
00312 NpPacket::getHeaderLength() {
00313 return m_headerLength;
00314 }
00315
00316
00321 unsigned int
00322 NpPacket::getHeaderLength(NpType packetType) {
00323 switch (packetType) {
00324 case NpPacket::Connect:
00325 return CP_HEADER_LENGTH;
00326 case NpPacket::Fin:
00327 return FP_HEADER_LENGTH;
00328 case NpPacket::ImHere:
00329 return IH_HEADER_LENGTH;
00330 case NpPacket::Discovery:
00331 return DP_HEADER_LENGTH;
00332 case NpPacket::Ping:
00333 case NpPacket::Pong:
00334 case NpPacket::Established:
00335 case NpPacket::Data:
00336 default:
00337 return NP_HEADER_LENGTH;
00338 }
00339 }
00340
00341
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364 void
00365 NpPacket::toStream(std::ostream& out) {
00366 out << "Dumping NpPacket (header length : " << m_headerLength << ")" << "\n";
00367 out << "Control type = " << getControlTypeString() << "\n";
00368 out << "Length = " << m_length << "\n";
00369 out << "VCN = " << m_vcn << "\n";
00370 }
00371
00372
00376 void
00377 NpPacket::dumpHeader(std::ostream& out)
00378 {
00379 unsigned char* raw_data = getRawData();
00380 out << "Dumping header..." << "\n";
00381 for (unsigned int i=0; i<m_headerLength; i++)
00382 {
00383 out << dec << i << ": " << hex << (unsigned short)raw_data[i] <<"\n";
00384 }
00385
00386 out << dec;
00387 }
00388
00389
00393 void
00394 NpPacket::dumpData(std::ostream& out) {
00395 out << "Dumping data..." << "\n";
00396 char tmpbuf[128];
00397 for (unsigned short i = 0; i < m_length; i++)
00398 {
00399
00400 OS_SPEC_SNPRINTF(tmpbuf, 128, "data[%i]=%#x\n", i, m_data[i]);
00401 out << tmpbuf;
00402 }
00403 out << "\n";
00404 }
00405
00406
00410 char*
00411 NpPacket::getControlTypeString() const
00412 {
00413 switch (m_controlType)
00414 {
00415 case (NpPacket::Data):
00416 return "Data";
00417 break;
00418 case (NpPacket::Connect):
00419 return "Connect";
00420 break;
00421 case (NpPacket::Established):
00422 return "Established";
00423 break;
00424 case (NpPacket::Fin):
00425 return "Fin";
00426 break;
00427 case (NpPacket::Discovery):
00428 return "Discovery";
00429 break;
00430 case (NpPacket::ImHere):
00431 return "ImHere";
00432 break;
00433 case (NpPacket::Ping):
00434 return "Ping";
00435 break;
00436 case (NpPacket::Pong):
00437 return "Pong";
00438 break;
00439 default:
00440 debug(DEBUG_PACKET, "ERROR: Not a valid command type packet: %d", (int)m_controlType);
00441 return "Not a valid command type packet";
00442 }
00443 }
00444
00445
00450 NpPacket*
00451 NpPacket::read(ConnectionInterface* connection)
00452 {
00453
00454 unsigned char* rawData = new unsigned char[MAX_PACKET_LENGTH];
00455 NpPacket* packet = NULL;
00456 int bytesRead;
00457 unsigned int packetLength = 0;
00458 NpPacket::NpType packetType;
00459
00460 if (!connection->isConnected()) {
00461 debug(DEBUG_PACKET, "trying to read from a Connection that isnt connected!");
00462 return NULL;
00463 }
00464
00465 memset(&rawData[0], 0, MAX_PACKET_LENGTH);
00466
00467
00468
00469 bytesRead = 0;
00470 bytesRead += connection->read(&rawData[0], MINI_HEADER_LENGTH, MINI_HEADER_LENGTH);
00471
00472
00473 if (bytesRead <= 0) {
00474 debug(DEBUG_PACKET, "socket read error: %s", strerror(errno));
00475 debug(DEBUG_PACKET, "%s", printWsaErrorCode());
00476 return NULL;
00477 }
00478
00479
00480 int versionNumber;
00481 int checkHeader = NpPacket::parseMiniHeader(rawData, &packetLength, &versionNumber, &packetType);
00482
00483
00484 if (checkHeader <= 0) {
00485
00486 debug(DEBUG_PACKET, "Error parsing mini header!");
00487 return NULL;
00488 }
00489
00490
00491
00492 int tmpBytesRead = connection->read(&rawData[bytesRead], packetLength - bytesRead, packetLength - bytesRead);
00493
00494 if (tmpBytesRead <= 0) {
00495 debug(DEBUG_CONN, "socket read error: %s", strerror(errno));
00496 return NULL;
00497 }
00498
00499 packet = NpPacket::decode(rawData, packetType);
00500 debug(DEBUG_PACKET, "Read packet: %d bytes, type %s", packetLength, packet->getControlTypeString());
00501
00502 return packet;
00503 }
00504
00505
00510 int
00511 NpPacket::write(ConnectionInterface* connection) {
00512 int bytesWritten = connection->write(getRawData(), getRawLength());
00513
00514 if ((unsigned int)bytesWritten != getRawLength()) {
00515 debug(DEBUG_ERR, "Error - did not send all data");
00516 }
00517
00518 return bytesWritten;
00519 }