182 lines
5.7 KiB
C++
182 lines
5.7 KiB
C++
/*
|
|
** Command & Conquer Generals Zero Hour(tm)
|
|
** Copyright 2025 Electronic Arts Inc.
|
|
**
|
|
** This program is free software: you can redistribute it and/or modify
|
|
** it under the terms of the GNU General Public License as published by
|
|
** the Free Software Foundation, either version 3 of the License, or
|
|
** (at your option) any later version.
|
|
**
|
|
** This program is distributed in the hope that it will be useful,
|
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
** GNU General Public License for more details.
|
|
**
|
|
** You should have received a copy of the GNU General Public License
|
|
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
|
|
#include <iostream>
|
|
#include <signal.h>
|
|
#ifdef _WINDOWS
|
|
#include <process.h> // *MUST* be included before ANY Wnet/Wlib headers if _REENTRANT is defined
|
|
#endif
|
|
|
|
#include "crc.h"
|
|
|
|
#include "configfile.h"
|
|
#include "threadfac.h"
|
|
|
|
#include "endian.h"
|
|
|
|
#include "xtime.h"
|
|
#include <filed.h>
|
|
#include <wstring.h>
|
|
#include <wdebug.h>
|
|
#include <udp.h>
|
|
|
|
|
|
|
|
|
|
/***************************************************************************
|
|
* Add_CRC -- Adds a value to a CRC *
|
|
* *
|
|
* INPUT: *
|
|
* crc ptr to crc *
|
|
* val value to add *
|
|
* *
|
|
* OUTPUT: *
|
|
* none *
|
|
* *
|
|
* WARNINGS: *
|
|
* none *
|
|
* *
|
|
* HISTORY: *
|
|
* 05/09/1995 BRR : Created. *
|
|
*=========================================================================*/
|
|
void Add_CRC(unsigned long *crc, unsigned char val)
|
|
{
|
|
int hibit;
|
|
|
|
//cout << "\t\t" << hex << val;
|
|
// val = htonl(val);
|
|
//cout << " / " << hex << val <<endl;
|
|
|
|
if ((*crc) & 0x80000000) {
|
|
hibit = 1;
|
|
} else {
|
|
hibit = 0;
|
|
}
|
|
|
|
(*crc) <<= 1;
|
|
(*crc) += val;
|
|
(*crc) += hibit;
|
|
|
|
//cout << hex << (*crc) <<endl;
|
|
}
|
|
|
|
|
|
void Build_Packet_CRC(unsigned char *buf, int len)
|
|
{
|
|
if (len < 5)
|
|
{
|
|
DBGMSG("Ack! Constructing a packet too small to hold a CRC!");
|
|
return;
|
|
}
|
|
if (!buf)
|
|
{
|
|
DBGMSG("Ack! Constructing a CRC for a void *");
|
|
return;
|
|
}
|
|
|
|
*((unsigned long *)buf) = 0;
|
|
|
|
unsigned long *crc_ptr = (unsigned long *)buf;
|
|
unsigned char *packetptr = (unsigned char*) (buf+4);
|
|
|
|
len -= 4; // look past CRC
|
|
|
|
for (int i=0 ; i<len ; i++) {
|
|
Add_CRC (crc_ptr, *packetptr++);
|
|
}
|
|
/*
|
|
int leftover = len & 3;
|
|
if (leftover) {
|
|
unsigned long val = 0;
|
|
unsigned char *c = (unsigned char *)packetptr;
|
|
for (int i=0; i<leftover; i++)
|
|
{
|
|
val += (c[i] << (i*8));
|
|
}
|
|
val = htonl(val);
|
|
Add_CRC (crc_ptr, val);
|
|
}
|
|
*/
|
|
*crc_ptr = htonl(*crc_ptr);
|
|
}
|
|
|
|
|
|
/***********************************************************************************************
|
|
* Passes_CRC_Check -- Checks the CRC for a packet *
|
|
* *
|
|
* *
|
|
* *
|
|
* INPUT: ptr to packet *
|
|
* *
|
|
* OUTPUT: true if packet passes CRC check *
|
|
* *
|
|
* WARNINGS: None *
|
|
* *
|
|
* HISTORY: *
|
|
* 10/5/99 1:26PM ST : Created *
|
|
* 1/9/2001 2:21PM MDC: Ripped from RA2 (WinsockInterfaceClass in wsproto.cpp/queue.cpp) *
|
|
* 1/31/2001 4:30PM MDC: Converted to network-byte-order so Sparc boxes can talk with Intels. *
|
|
* 2/1/2001 4:07PM MDC: Converted back to Intel order to avoid messing with C&C packets *
|
|
*=============================================================================================*/
|
|
bool Passes_CRC_Check(unsigned char *buf, int len)
|
|
{
|
|
if (len < 5)
|
|
{
|
|
DBGMSG("Recieved packet too small to contain a CRC");
|
|
return false;
|
|
}
|
|
if (!buf)
|
|
{
|
|
DBGMSG("Ack! Checking a CRC for a void *");
|
|
return false;
|
|
}
|
|
|
|
unsigned long crc = 0;
|
|
|
|
unsigned long *crc_ptr = &crc;
|
|
unsigned char *packetptr = (unsigned char*) (buf+4);
|
|
|
|
len -= 4; // remove the CRC from packet size - just look at payload
|
|
|
|
for (int i=0 ; i<len ; i++) {
|
|
Add_CRC (crc_ptr, *packetptr++);
|
|
}
|
|
/*
|
|
int leftover = len & 3;
|
|
if (leftover) {
|
|
unsigned long val = 0;
|
|
unsigned char *c = (unsigned char *)packetptr;
|
|
for (int i=0; i<leftover; i++)
|
|
{
|
|
val += (c[i] << (i*8));
|
|
}
|
|
val = htonl(val);
|
|
Add_CRC (crc_ptr, val);
|
|
}
|
|
*/
|
|
crc = htonl(crc);
|
|
|
|
if (crc == *((unsigned long *)buf)) {
|
|
return (true);
|
|
}
|
|
|
|
DBGMSG("Invalid packet CRC");
|
|
return (false);
|
|
}
|