PiB
04-27-2013, 02:45 PM
I have tried to rewrite the CRC16 code (which looks like it's been generated from some assembly from the official client) used for checksuming packets. I ended up with code that looked very much like the Ethernet CRC32. If you look at the lookup tables in CRC16.cpp and CRC32.cpp you'll see they have the same values.
// This is computed as the lowest 16 bits of an Ethernet CRC32 checksum
// where the key is prepended to the data in little endian order.
uint8 keyBuf[] = {(uint8)((key >> 0) & 0xff),
(uint8)((key >> 8) & 0xff),
(uint8)((key >> 16) & 0xff),
(uint8)((key >> 24) & 0xff)};
uint32 crc = CRC32::Update(keyBuf, sizeof(uint32));
crc = CRC32::Update(buf, size, crc);
return CRC32::Finish(crc) & 0xffff;
This seems to work pretty well as I can log with a Titanium client with these changes in EQEmu. I have commited the changes to a GitHub fork for review if anyone is interested in getting rid of the assembly translation: https://github.com/pixelbound/Server/tree/crc16-using-crc32.
// This is computed as the lowest 16 bits of an Ethernet CRC32 checksum
// where the key is prepended to the data in little endian order.
uint8 keyBuf[] = {(uint8)((key >> 0) & 0xff),
(uint8)((key >> 8) & 0xff),
(uint8)((key >> 16) & 0xff),
(uint8)((key >> 24) & 0xff)};
uint32 crc = CRC32::Update(keyBuf, sizeof(uint32));
crc = CRC32::Update(buf, size, crc);
return CRC32::Finish(crc) & 0xffff;
This seems to work pretty well as I can log with a Titanium client with these changes in EQEmu. I have commited the changes to a GitHub fork for review if anyone is interested in getting rid of the assembly translation: https://github.com/pixelbound/Server/tree/crc16-using-crc32.