void CPacketUtils::EncryptPacket(PacketData& packet) { if(packet.size() <= sizeof(PACKETHEADER)) { assert(0); return; } uint8* data = &packet[0]; uint32 size = packet.size(); data += 0x10; size -= 0x10; while(1) { uint32 subPacketSize = *reinterpret_cast<uint16*>(data); size -= subPacketSize; subPacketSize -= 0x10; data += 0x10; for(unsigned int i = 0; i < subPacketSize; i += 8) { Blowfish_encipher( reinterpret_cast<uint32*>(data + i), reinterpret_cast<uint32*>(data + i + 4)); } data += subPacketSize; if(size == 0) break; } }
bool Host::broadcast(ChannelID channel, PacketType type, const PacketData& data) { if (!isServer()) { logError("Only the server is allowed to broadcast"); return false; } uint32 flags = 0; if (type == RELIABLE) flags |= ENET_PACKET_FLAG_RELIABLE; else { if (type == UNSEQUENCED) flags |= ENET_PACKET_FLAG_UNSEQUENCED; flags |= ENET_PACKET_FLAG_NO_ALLOCATE; } ENetPacket* packet = enet_packet_create(data.data(), data.size(), flags); if (!packet) { logError("Failed to create ENet packet"); return false; } enet_host_broadcast((ENetHost*) m_object, channel, packet); return true; }
bool Peer::sendPacket(ChannelID channel, PacketType type, const PacketData& data) { uint32 flags = 0; if (type == RELIABLE) flags |= ENET_PACKET_FLAG_RELIABLE; else { if (type == UNSEQUENCED) flags |= ENET_PACKET_FLAG_UNSEQUENCED; flags |= ENET_PACKET_FLAG_NO_ALLOCATE; } ENetPacket* packet = enet_packet_create(data.data(), data.size(), flags); if (!packet) { logError("Failed to create ENet packet"); return false; } if (enet_peer_send((ENetPeer*) m_peer, channel, packet) < 0) { logError("Failed to send ENet packet to peer %s", m_name.c_str()); return false; } return true; }
std::string CPacketUtils::DumpPacket(const PacketData& packet) { std::string result; static const unsigned int lineWidth = 0x10; for(unsigned int i = 0; i < (packet.size() + lineWidth - 1) / lineWidth; i++) { for(unsigned int j = 0; j < lineWidth; j++) { unsigned int offset = i * lineWidth + j; if(offset >= packet.size()) { result += " "; } else { char byteString[4]; sprintf(byteString, "%0.2X ", packet[offset]); result += byteString; } } result += " "; for(unsigned int j = 0; j < lineWidth; j++) { unsigned int offset = i * lineWidth + j; if(offset >= packet.size()) continue; char character = packet[offset]; if((character >= 0) && (isdigit(character) || isalpha(character))) { result += character; } else { result += "."; } } result += "\r\n"; } return result; }
void CPacketUtils::EncryptPacket(PacketData& packet) { if (packet.size() <= sizeof(PACKETHEADER)) { assert(0); return; } uint8_t* data = &packet[0]; uint32_t size = (uint32_t)packet.size(); data += sizeof(PACKETHEADER); size -= sizeof(PACKETHEADER); if (size % 8 != 0) { return; } while (1) { SUBPACKETHEADER subPacket = *reinterpret_cast<SUBPACKETHEADER*>(data); uint32_t subPacketSize = subPacket.subPacketSize; size -= subPacketSize; subPacketSize -= sizeof(SUBPACKETHEADER); data += sizeof(SUBPACKETHEADER); for (unsigned int i = 0; i < subPacketSize; i += 8) { Blowfish_encipher( reinterpret_cast<uint32_t*>(data + i), reinterpret_cast<uint32_t*>(data + i + 4)); } data += subPacketSize; if (size == 0) break; } }
SubPacketArray CPacketUtils::SplitPacketSubPacket(const PacketData& packet) { printf("%s", CPacketUtils::DumpPacket(packet).c_str()); SubPacketArray subPackets; if (packet.size() < sizeof(PACKETHEADER)) { CLog::GetInstance().LogError(LOG_NAME, "Packet to split is smaller than PACKETHEADER.\r\n"); return subPackets; } const uint8_t* packetData = packet.data(); PACKETHEADER header = *reinterpret_cast<const PACKETHEADER*>(packetData); assert(packet.size() == header.packetSize); uint32_t currentSize = header.packetSize - sizeof(PACKETHEADER); packetData += sizeof(PACKETHEADER); while (currentSize != 0) { SUBPACKETHEADER subHeader = *reinterpret_cast<const SUBPACKETHEADER*>(packetData); if (subHeader.subPacketSize == 0) { CLog::GetInstance().LogError(LOG_NAME, "Got zero sized subpacket. Stopping packet processing.\r\n"); break; } if (subHeader.subPacketSize > currentSize) { CLog::GetInstance().LogError(LOG_NAME, "Subpacket doesn't fit in packet. Stopping packet processing.\r\n"); break; } auto subPacket = PacketData(packetData, packetData + subHeader.subPacketSize); subPackets.push_back(subPacket); currentSize -= subHeader.subPacketSize; packetData += subHeader.subPacketSize; } return subPackets; }
uint16_t send( const PacketData &packet ) { return send( packet.data(), packet.size() ); }