int cProtocol125::ParsePacket(unsigned char a_PacketType) { switch (a_PacketType) { default: return PARSE_UNKNOWN; case PACKET_ANIMATION: return ParseArmAnim(); case PACKET_BLOCK_DIG: return ParseBlockDig(); case PACKET_BLOCK_PLACE: return ParseBlockPlace(); case PACKET_CHAT: return ParseChat(); case PACKET_CREATIVE_INVENTORY_ACTION: return ParseCreativeInventoryAction(); case PACKET_DISCONNECT: return ParseDisconnect(); case PACKET_HANDSHAKE: return ParseHandshake(); case PACKET_KEEP_ALIVE: return ParseKeepAlive(); case PACKET_LOGIN: return ParseLogin(); case PACKET_PACKET_ENTITY_ACTION: return ParseEntityAction(); case PACKET_PING: return ParsePing(); case PACKET_PLAYER_ABILITIES: return ParsePlayerAbilities(); case PACKET_PLAYER_LOOK: return ParsePlayerLook(); case PACKET_PLAYER_MOVE_LOOK: return ParsePlayerMoveLook(); case PACKET_PLAYER_ON_GROUND: return ParsePlayerOnGround(); case PACKET_PLAYER_POS: return ParsePlayerPosition(); case PACKET_PLUGIN_MESSAGE: return ParsePluginMessage(); case PACKET_RESPAWN: return ParseRespawn(); case PACKET_SLOT_SELECTED: return ParseSlotSelected(); case PACKET_UPDATE_SIGN: return ParseUpdateSign(); case PACKET_USE_ENTITY: return ParseUseEntity(); case PACKET_ENCHANT_ITEM: return ParseEnchantItem(); case PACKET_WINDOW_CLICK: return ParseWindowClick(); case PACKET_WINDOW_CLOSE: return ParseWindowClose(); } }
void CGnutellaSocket::OnReceive(int nErrorCode) { TRACE("OnRead\n"); /* if (nErrorCode) { ASSERT(0); return; } */ if (m_state == 0 || m_state == 1) { /* time_t timer1; time(&timer1); double diff = difftime(timer1, m_timer0); m_timer0 = timer1; ATLTRACE("", diff); */ ULONG n; ioctlsocket(m_socket, FIONREAD, &n); char buf[256+1]; while (n) { int len = 256; if (len > n) len = n; int nread = Receive(buf, len); //if (nread == SOCKET_ERROR) if (nread < len) { m_state = -1; Close(); return; } n -= nread; buf[nread] = 0; m_strHandshake += buf; } /* std::string line; while (1) { line = ReadLine(); m_strHandshake += line + "\r\n"; if (line.length() == 0) break; } */ if (m_strHandshake.length() > 4096) { // Handshake overflow ASSERT(0); m_state = -1; Close(); return;//break; } if (m_state == 0) { if (m_strHandshake.length() >= 12) { if (strncmp(m_strHandshake.c_str(), "GNUTELLA/0.6", 12)) { // Not a gnutella peer (disconnect) m_state = -1; Close(); return;//break; } m_state = 1; // Now we know it's a gnutella peer (keep receiving handshake) } } if (m_state == 1) { if (strstr(m_strHandshake.c_str(), "\r\n\r\n")) { m_state = 2; // Have read entire handshake string } } if (m_state == 2) { int m_code = ParseHandshake(); m_pComm->ProcessHeaders(this); if (m_code == 200) // OK { m_state = 3; char* str = "GNUTELLA/0.6 200 OK\r\n" "\r\n"; // char* str = "GNUTELLA OK\n\n"; int nWritten = Send(str, strlen(str)); if (nWritten != strlen(str)) { ASSERT(0); } // PostMessage(m_pComm->m_hWnd, WM_USER+102, (LPARAM)(IConnection*)this, m_code); // m_pComm->m_client->OnConnection(this); // Ping { GnutellaHeader ping; CoCreateGuid(&ping.Guid); // ??? ping.PayloadType = GnutellaPing; ping.TTL = 7; ping.Hops = 0; ping.PayloadLength = 0; int wrote = Send((const char*)&ping, sizeof(ping)); } } else { Close(); /* char* str = "GNUTELLA/0.6 503 FAIL\r\n" "\r\n"; int nWritten = Send(str, strlen(str)); if (nWritten != strlen(str)) { ASSERT(0); } */ } } } else if (m_state == 3) { int nread = Receive(m_packetbuf+m_nbufbytes, 32768-m_nbufbytes); if (nread == -1) { m_state = -1; Close(); return; } int nbufbytes = m_nbufbytes + nread; // Process all complete packets bool bContinue; int offset = 0; int bytesleft; do { bytesleft = nbufbytes - offset; if (bytesleft < sizeof(GnutellaHeader)) { // Incomplete packet bContinue = false; } else { GnutellaHeader* hdr = (GnutellaHeader*)(m_packetbuf+offset); if((hdr->PayloadType == 0x00 && hdr->PayloadLength < 32768) || (hdr->PayloadType == 0x01 && hdr->PayloadLength >= 14 && hdr->PayloadLength < 32768) || (hdr->PayloadType == 0x02 && hdr->PayloadLength > 0 && hdr->PayloadLength < 32768) || (hdr->PayloadType == 0x30 && hdr->PayloadLength > 2 && hdr->PayloadLength < 32768) || (hdr->PayloadType == 0x31 && hdr->PayloadLength < 32768) || (hdr->PayloadType == 0x32 && hdr->PayloadLength < 32768) || (hdr->PayloadType == 0x40 && hdr->PayloadLength >= 26 && hdr->PayloadLength < 32768) || (hdr->PayloadType == 0x80 && hdr->PayloadLength > 2 && hdr->PayloadLength <= 230) || (hdr->PayloadType == 0x81 && hdr->PayloadLength > 26 && hdr->PayloadLength <= 32768)) { DWORD packetlen = sizeof(GnutellaHeader) + hdr->PayloadLength; if (bytesleft < packetlen) { // Incomplete packet bContinue = false; } else { ProcessPacket(hdr); offset += packetlen; bContinue = true; } } else { bContinue = false; m_state = -1; Close(); return; } } } while (bContinue); // Move the leftover bytes to the beginning of the buffer if (bytesleft) { memmove(m_packetbuf, m_packetbuf+offset, bytesleft); } m_nbufbytes = bytesleft; } }