diff --git a/EQ2/source/common/EQPacket.cpp b/EQ2/source/common/EQPacket.cpp index 22b300f21..e7e20c3ee 100644 --- a/EQ2/source/common/EQPacket.cpp +++ b/EQ2/source/common/EQPacket.cpp @@ -555,6 +555,31 @@ void EQProtocolPacket::ChatEncode(unsigned char *buffer, int size, int EncodeKey } } +bool EQProtocolPacket::IsProtocolPacket(const unsigned char* in_buff, uint32_t len, bool bTrimCRC) { + bool ret = false; + uint16_t opcode = ntohs(*(uint16_t*)in_buff); + uint32_t offset = 2; + + switch (opcode) { + case OP_SessionRequest: + case OP_SessionDisconnect: + case OP_KeepAlive: + case OP_SessionStatResponse: + case OP_Packet: + case OP_Combined: + case OP_Fragment: + case OP_Ack: + case OP_OutOfOrderAck: + case OP_OutOfSession: + { + ret = true; + break; + } + } + + return ret; +} + void DumpPacketHex(const EQApplicationPacket* app) diff --git a/EQ2/source/common/EQPacket.h b/EQ2/source/common/EQPacket.h index 6a9b61202..6a9801837 100644 --- a/EQ2/source/common/EQPacket.h +++ b/EQ2/source/common/EQPacket.h @@ -104,6 +104,8 @@ public: static uint32 Compress(const unsigned char *buffer, const uint32 length, unsigned char *newbuf, uint32 newbufsize); static void ChatDecode(unsigned char *buffer, int size, int DecodeKey); static void ChatEncode(unsigned char *buffer, int size, int EncodeKey); + static bool IsProtocolPacket(const unsigned char* in_buff, uint32_t len, bool bTrimCRC); + EQProtocolPacket *Copy() { EQProtocolPacket* new_packet = new EQProtocolPacket(opcode,pBuffer,size); new_packet->eq2_compressed = this->eq2_compressed; diff --git a/EQ2/source/common/EQStream.cpp b/EQ2/source/common/EQStream.cpp index 482d6201a..76e6057cd 100644 --- a/EQ2/source/common/EQStream.cpp +++ b/EQ2/source/common/EQStream.cpp @@ -239,17 +239,28 @@ void EQStream::ProcessPacket(EQProtocolPacket *p) #ifdef LE_DEBUG LogWrite(PACKET__DEBUG, 0, "Packet", "OP_Combined Packet %i (%u) (%u): ", count, subpacket_length, processed); #endif - EQProtocolPacket *subp=new EQProtocolPacket(p->pBuffer+processed+offset,subpacket_length); - subp->copyInfo(p); + bool isSubPacket = EQProtocolPacket::IsProtocolPacket(p->pBuffer + processed + offset, subpacket_length, false); + if (isSubPacket) { + EQProtocolPacket* subp = new EQProtocolPacket(p->pBuffer + processed + offset, subpacket_length); + subp->copyInfo(p); + //I've seen some garbage packets get sent with wrong protocol opcodes but the rest of the combine is still correct + //So don't break if GetProtocolPacket fails #ifdef LE_DEBUG - LogWrite(PACKET__DEBUG, 0, "Packet", "Opcode %i:", subp->opcode); - DumpPacket(subp); + LogWrite(PACKET__DEBUG, 0, "Packet", "Opcode %i:", subp->opcode); + DumpPacket(subp); #endif - ProcessPacket(subp); + ProcessPacket(subp); #ifdef LE_DEBUG - DumpPacket(subp); + DumpPacket(subp); #endif - delete subp; + delete subp; + } + else if (ntohs(*reinterpret_cast(p->pBuffer + processed + offset)) > 0x1e) { + //Garbage packet? + crypto->RC4Decrypt(p->pBuffer + processed + offset, subpacket_length); + LogWrite(PACKET__ERROR, 0, "Packet", "Garbage packet?!:"); + DumpPacket(p->pBuffer + processed + offset, subpacket_length); + } processed+=subpacket_length+offset; } break;