Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

NpPacket.cpp

Go to the documentation of this file.
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 } // NpPacket ctor
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 } // NpPacket ctor
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 } // NpPacket ctor
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 } // NpPacket ctor
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: // Ping, Pong, Established
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: // Ping, Pong, Established
00148             npPacket = new NpPacket(rawData);
00149             break;
00150         }
00151         MEMCHECK(npPacket);
00152     debug(DEBUG_PACKET, "Decoded %s packet", npPacket->getControlTypeString()); 
00153         return npPacket;
00154 } // fn decode
00155 
00156 
00163 int 
00164 NpPacket::parseMiniHeader(unsigned char* rawData, unsigned int* rawLength,
00165                           int* versionNumber, NpType* packetType) {
00166     
00167     // Check for correct version number
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     // Check for valid packet type
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     // get header length
00182     int headerLength = NpPacket::getHeaderLength(*packetType);
00183 
00184     // get raw length
00185     memcpy(rawLength, &rawData[LengthOffset], S_USHORT);
00186     *rawLength = ntohs(*rawLength) + headerLength;
00187 
00188     // Do sanity check on raw length of packet
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 } // fn parseMiniHeader
00196 
00197 
00198 NpPacket::~NpPacket()
00199 {
00200         if (m_controlType != NpPacket::Data) //only need to delete for control
00201         {
00202         if (m_rawData != NULL) {
00203                     delete [] m_rawData;
00204                         m_rawData = NULL;
00205         }
00206         }
00207 } // dtor
00208 
00209 
00210 unsigned int 
00211 NpPacket::getVcn() {
00212         return m_vcn;
00213 } // fn getSrcVcn
00214 
00215 
00216 void 
00217 NpPacket::setVcn(unsigned int vcn) {
00218         m_vcn = vcn;
00219 } // fn setSrcVcn
00220 
00221 
00222 void 
00223 NpPacket::setPacketType(NpType type) {
00224     this->m_controlType = type;
00225 } // fn setPacketType
00226 
00227 
00228 unsigned char* 
00229 NpPacket::getData()
00230 {
00231         return m_data;
00232 } // fn getData
00233 
00234 
00235 unsigned int 
00236 NpPacket::getDataLength() const {
00237         return (int)m_length;
00238 } // fn getDataLength
00239 
00240 
00247 unsigned char* 
00248 NpPacket::getRawData()
00249 {
00250 
00251         // The buffer will be created if it hasnt been
00252         // this means we are the originator of the packet
00253         if (!m_rawData) {
00254                 m_rawData = new unsigned char[m_length + m_headerLength];
00255         }
00256         MEMCHECK(m_rawData);
00257 
00258     // encode the version number
00259     m_rawData[VersionNumberOffset] = (unsigned char)(VERSION_NUMBER << 4);
00260 
00261     // encode the packet type
00262         m_rawData[PacketTypeOffset] = (unsigned char)(m_rawData[PacketTypeOffset] | (m_controlType & 0x0F));
00263 
00264     // encode the length
00265         unsigned short tmpUshort;
00266     tmpUshort = (unsigned short)(htons(m_length));
00267         memcpy(&m_rawData[LengthOffset], &tmpUshort, S_USHORT);
00268     
00269     // encode the VCN
00270     unsigned int tmpUint;
00271         tmpUint = htonl(m_vcn);
00272         memcpy(&m_rawData[VcnOffset], &tmpUint, S_UINT);
00273 
00274         return m_rawData;
00275 } // fn getRawData
00276 
00277 
00281 unsigned int 
00282 NpPacket::getRawLength() const
00283 {
00284         return m_length + m_headerLength;
00285 } // fn getRawLength
00286 
00287 
00291 NpPacket::NpType 
00292 NpPacket::getPacketType() const
00293 {
00294         return m_controlType;
00295 } // fn getControlType
00296 
00297 
00301 bool 
00302 NpPacket::isControlPacket() const
00303 {
00304         return m_controlType != Data;
00305 } // fn isControlType
00306 
00307 
00311 unsigned int 
00312 NpPacket::getHeaderLength() {
00313         return m_headerLength;
00314 } // fn getHeaderLength
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 } // fn getHeaderLength
00340 
00341 
00346 /* Not used
00347 int NpPacket::getPacketLength(unsigned char* rawData) {
00348     
00349         m_controlType = (NpType)ntohs((rawData[0] & 0xF0) << 4);
00350 
00351     m_headerLength = NpPacket::getHeaderLength(m_controlType);
00352         memcpy(&m_length, &rawData[1], S_UINT);
00353         m_length = ntohl(m_length);
00354 
00355     // Do sanity check (add more...)
00356     if (m_length + m_headerLength > MAX_PACKET_LENGTH) {
00357         return -1;
00358     }
00359 
00360     return m_headerLength + m_length;
00361 } // fn getPacketLength
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 } // fn toStream
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         //delete raw_data;
00386         out << dec;
00387 } // fn dumpHeader
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                 // Could not make this work with cout - even when using "hex"
00400                 OS_SPEC_SNPRINTF(tmpbuf, 128, "data[%i]=%#x\n", i, m_data[i]);
00401         out << tmpbuf;
00402         }// for
00403         out << "\n";
00404 } // fn dumpData
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         } // switch
00443 } // fn getControlTypeString
00444 
00445 
00450 NpPacket*
00451 NpPacket::read(ConnectionInterface* connection)
00452 {
00453     // the raw packet
00454     unsigned char* rawData = new unsigned char[MAX_PACKET_LENGTH]; 
00455     NpPacket* packet = NULL;
00456     int bytesRead;
00457     unsigned int packetLength = 0;  // Length of the packet we are going to read
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     // Read the mini-header which allows us to determine the length
00468     // of the rest of the packet
00469     bytesRead = 0;
00470     bytesRead += connection->read(&rawData[0], MINI_HEADER_LENGTH, MINI_HEADER_LENGTH);
00471 
00472     // check for read errors
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     // This returns the raw packet length
00480     int versionNumber;
00481     int checkHeader = NpPacket::parseMiniHeader(rawData, &packetLength, &versionNumber, &packetType);
00482 
00483     // check the packet length
00484     if (checkHeader <= 0) { // an error occured
00485         // need to close the connection here becasue this peer sent us bad stuff
00486         debug(DEBUG_PACKET, "Error parsing mini header!");
00487         return NULL;
00488     }
00489 
00490     // Read the rest of the packet
00491     // by this time, bytesRead should be == MINI_HEADER_LENGTH
00492     int tmpBytesRead = connection->read(&rawData[bytesRead], packetLength - bytesRead, packetLength - bytesRead);
00493     // check for read errors
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 } // fn read
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 } // fn writePacket

Generated at Thu Jul 11 13:31:51 2002 for Peekabooty by doxygen1.2.9 written by Dimitri van Heesch, © 1997-2001