diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Server/Protocol/PacketLog.cpp | 64 | ||||
-rw-r--r-- | src/server/game/Server/WorldSocket.cpp | 18 | ||||
-rw-r--r-- | src/server/game/Server/WorldSocket.h | 4 | ||||
-rw-r--r-- | src/server/worldserver/worldserver.conf.dist | 4 |
4 files changed, 72 insertions, 18 deletions
diff --git a/src/server/game/Server/Protocol/PacketLog.cpp b/src/server/game/Server/Protocol/PacketLog.cpp index ed5a3b52871..6ef33133615 100644 --- a/src/server/game/Server/Protocol/PacketLog.cpp +++ b/src/server/game/Server/Protocol/PacketLog.cpp @@ -17,9 +17,36 @@ #include "PacketLog.h" #include "Config.h" -#include "ByteBuffer.h" #include "WorldPacket.h" +#pragma pack(push, 1) + +// Packet logging structures in PKT 3.1 format +struct LogHeader +{ + char Signature[3]; + uint16 FormatVersion; + uint8 SnifferId; + uint32 Build; + char Locale[4]; + uint8 SessionKey[40]; + uint32 SniffStartUnixtime; + uint32 SniffStartTicks; + uint32 OptionalDataSize; +}; + +struct PacketHeader +{ + char Direction[4]; + uint32 ConnectionId; + uint32 ArrivalTicks; + uint32 OptionalDataSize; + uint32 Length; + uint32 Opcode; +}; + +#pragma pack(pop) + PacketLog::PacketLog() : _file(NULL) { Initialize(); @@ -38,25 +65,42 @@ void PacketLog::Initialize() std::string logsDir = sConfigMgr->GetStringDefault("LogsDir", ""); if (!logsDir.empty()) - if ((logsDir.at(logsDir.length()-1) != '/') && (logsDir.at(logsDir.length()-1) != '\\')) + if ((logsDir.at(logsDir.length() - 1) != '/') && (logsDir.at(logsDir.length() - 1) != '\\')) logsDir.push_back('/'); std::string logname = sConfigMgr->GetStringDefault("PacketLogFile", ""); if (!logname.empty()) + { _file = fopen((logsDir + logname).c_str(), "wb"); + + LogHeader header; + header.Signature[0] = 'P'; header.Signature[1] = 'K'; header.Signature[2] = 'T'; + header.FormatVersion = 0x0301; + header.SnifferId = 'T'; + header.Build = 12340; + header.Locale[0] = 'e'; header.Locale[1] = 'n'; header.Locale[2] = 'U'; header.Locale[3] = 'S'; + std::memset(header.SessionKey, 0, sizeof(header.SessionKey)); + header.SniffStartUnixtime = time(NULL); + header.SniffStartTicks = getMSTime(); + header.OptionalDataSize = 0; + + fwrite(&header, sizeof(header), 1, _file); + } } void PacketLog::LogPacket(WorldPacket const& packet, Direction direction) { - ByteBuffer data(4+4+4+1+packet.size()); - data << int32(packet.GetOpcode()); - data << int32(packet.size()); - data << uint32(time(NULL)); - data << uint8(direction); + PacketHeader header; + *reinterpret_cast<uint32*>(header.Direction) = direction == CLIENT_TO_SERVER ? 0x47534d43 : 0x47534d53; + header.ConnectionId = 0; + header.ArrivalTicks = getMSTime(); + header.OptionalDataSize = 0; + header.Length = packet.size() + 4; + header.Opcode = packet.GetOpcode(); - for (uint32 i = 0; i < packet.size(); i++) - data << packet[i]; + fwrite(&header, sizeof(header), 1, _file); + if (!packet.empty()) + fwrite(packet.contents(), 1, packet.size(), _file); - fwrite(data.contents(), 1, data.size(), _file); fflush(_file); } diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index bbb86cf3d2f..3b9749dfd3b 100644 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -25,6 +25,7 @@ #include "Opcodes.h" #include "ScriptMgr.h" #include "SHA1.h" +#include "PacketLog.h" using boost::asio::ip::tcp; using boost::asio::streambuf; @@ -53,11 +54,10 @@ void WorldSocket::HandleSendAuthSession() BigNumber seed2; seed2.SetRand(16 * 8); packet.append(seed2.AsByteArray(16).get(), 16); // new encryption seeds - + AsyncWrite(packet); } - void WorldSocket::AsyncReadHeader() { auto self(shared_from_this()); @@ -106,6 +106,11 @@ void WorldSocket::AsyncReadData(size_t dataSize) std::memcpy(packet.contents(), &_readBuffer[sizeof(ClientPktHeader)], header->size); } + if (sPacketLog->CanLogPacket()) + sPacketLog->LogPacket(packet, CLIENT_TO_SERVER); + + TC_LOG_TRACE("network.opcode", "C->S: %s %s", (_worldSession ? _worldSession->GetPlayerInfo() : GetRemoteIpAddress()).c_str(), GetOpcodeNameForLogging(opcode).c_str()); + switch (opcode) { case CMSG_PING: @@ -154,15 +159,20 @@ void WorldSocket::AsyncReadData(size_t dataSize) void WorldSocket::AsyncWrite(WorldPacket const& packet) { + if (sPacketLog->CanLogPacket()) + sPacketLog->LogPacket(packet, SERVER_TO_CLIENT); + + TC_LOG_TRACE("network.opcode", "S->C: %s %s", (_worldSession ? _worldSession->GetPlayerInfo() : GetRemoteIpAddress()).c_str(), GetOpcodeNameForLogging(packet.GetOpcode()).c_str()); + ServerPktHeader header(packet.size() + 2, packet.GetOpcode()); _authCrypt.EncryptSend((uint8*)header.header, header.getHeaderLength()); auto data = new char[header.getHeaderLength() + packet.size()]; std::memcpy(data, (char*)header.header, header.getHeaderLength()); - + if (!packet.empty()) std::memcpy(data + header.getHeaderLength(), (char const*)packet.contents(), packet.size()); - + // Use a shared_ptr here to prevent leaking memory after the async operation has completed std::shared_ptr<char> buffer(data, [=](char* _b) { diff --git a/src/server/game/Server/WorldSocket.h b/src/server/game/Server/WorldSocket.h index a6520a70846..039859b5579 100644 --- a/src/server/game/Server/WorldSocket.h +++ b/src/server/game/Server/WorldSocket.h @@ -51,8 +51,8 @@ public: void Start(); - const std::string GetRemoteIpAddress() const { return _socket.remote_endpoint().address().to_string(); }; - unsigned short GetRemotePort() const { return _socket.remote_endpoint().port(); } + std::string GetRemoteIpAddress() const { return _socket.remote_endpoint().address().to_string(); }; + uint16 GetRemotePort() const { return _socket.remote_endpoint().port(); } void CloseSocket() { _socket.close(); }; bool IsOpen() { return _socket.is_open(); }; diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index c4e3ad832a7..4e837d0a1ba 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -413,8 +413,8 @@ PidFile = "" # # PacketLogFile # Description: Binary packet logging file for the world server. -# Filename extension must be .bin to be parsable with WowPacketParser. -# Example: "World.bin" - (Enabled) +# Filename extension must be .pkt to be parsable with WowPacketParser. +# Example: "World.pkt" - (Enabled) # Default: "" - (Disabled) PacketLogFile = "" |