mirror of
https://github.com/electronicarts/CnC_Renegade.git
synced 2026-05-02 13:56:59 +02:00
Initial commit of Command & Conquer Renegade source code.
This commit is contained in:
@@ -0,0 +1,488 @@
|
||||
/*
|
||||
** Command & Conquer Renegade(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/>.
|
||||
*/
|
||||
|
||||
//
|
||||
// Filename: nicenum.cpp
|
||||
// Author: Tom Spencer-Smith
|
||||
// Date: Dec 1999
|
||||
// Description:
|
||||
//
|
||||
|
||||
#include "nicenum.h"
|
||||
|
||||
#include <winsock.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "wwdebug.h"
|
||||
#include "netutil.h"
|
||||
#include "useroptions.h"
|
||||
#include "GameSpy_QnR.h"
|
||||
|
||||
//
|
||||
// Class statics
|
||||
//
|
||||
ULONG cNicEnum::NicList[];
|
||||
USHORT cNicEnum::NumNics = 0;
|
||||
ULONG cNicEnum::GSNicList[];
|
||||
USHORT cNicEnum::NumGSNics = 0;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
void
|
||||
cNicEnum::Init
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
WWDEBUG_SAY(("cNicEnum::Init\n"));
|
||||
|
||||
WSADATA wsa_data;
|
||||
int startup_rc = ::WSAStartup(MAKEWORD(1, 1), &wsa_data);
|
||||
if (startup_rc != 0)
|
||||
{
|
||||
WWDEBUG_SAY((" WSAStartup failed!\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Retrieve list of nic's
|
||||
//
|
||||
ULONG local_addresses[MAX_NICS];
|
||||
ULONG num_addresses = Enumerate_Nics(local_addresses, MAX_NICS);
|
||||
WWASSERT(num_addresses <= MAX_NICS);
|
||||
|
||||
WWDEBUG_SAY((" Found %d NIC(s)\n", num_addresses));
|
||||
|
||||
USHORT index = 0;
|
||||
USHORT class_1 = 0;
|
||||
USHORT class_2 = 0;
|
||||
|
||||
//
|
||||
// First, extract the non-internet addressable nicks, ordered on general usage.
|
||||
//
|
||||
ULONG lan_addresses[MAX_NICS];
|
||||
ULONG num_lan_addresses = 0;
|
||||
|
||||
//
|
||||
// First, scan for 10.*.*.* addresses
|
||||
//
|
||||
for (index = 0; index < num_addresses; index++)
|
||||
{
|
||||
class_1 = (::ntohl(local_addresses[index]) & 0xff000000) >> 24;
|
||||
|
||||
if (class_1 == 10)
|
||||
{
|
||||
lan_addresses[num_lan_addresses++] = local_addresses[index];
|
||||
local_addresses[index] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Next, scan for 192.168.*.* addresses
|
||||
//
|
||||
for (index = 0; index < num_addresses; index++)
|
||||
{
|
||||
class_1 = (::ntohl(local_addresses[index]) & 0xff000000) >> 24;
|
||||
class_2 = (::ntohl(local_addresses[index]) & 0x00ff0000) >> 16;
|
||||
|
||||
if (class_1 == 192 && class_2 == 168)
|
||||
{
|
||||
lan_addresses[num_lan_addresses++] = local_addresses[index];
|
||||
local_addresses[index] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Next, scan for 172.16-31.*.* addresses
|
||||
//
|
||||
for (index = 0; index < num_addresses; index++)
|
||||
{
|
||||
class_1 = (::ntohl(local_addresses[index]) & 0xff000000) >> 24;
|
||||
class_2 = (::ntohl(local_addresses[index]) & 0x00ff0000) >> 16;
|
||||
|
||||
if (class_1 == 172 && class_2 >= 16 && class_2 <= 31)
|
||||
{
|
||||
lan_addresses[num_lan_addresses++] = local_addresses[index];
|
||||
local_addresses[index] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Finally, scan for 169.254.*.* addresses (IP autoconfiguration)
|
||||
//
|
||||
for (index = 0; index < num_addresses; index++)
|
||||
{
|
||||
class_1 = (::ntohl(local_addresses[index]) & 0xff000000) >> 24;
|
||||
class_2 = (::ntohl(local_addresses[index]) & 0x00ff0000) >> 16;
|
||||
|
||||
if (class_1 == 169 && class_2 == 254)
|
||||
{
|
||||
lan_addresses[num_lan_addresses++] = local_addresses[index];
|
||||
local_addresses[index] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
WWDEBUG_SAY((" Of which %d are non-internet addressable.\n", num_lan_addresses));
|
||||
|
||||
//
|
||||
// Next, copy the Internet addressable addresses. Weed out localhost and multicast
|
||||
// addresses.
|
||||
//
|
||||
|
||||
ULONG internet_addresses[MAX_NICS];
|
||||
ULONG num_internet_addresses = 0;
|
||||
|
||||
for (index = 0; index < num_addresses; index++)
|
||||
{
|
||||
if (local_addresses[index] != 0)
|
||||
{
|
||||
class_1 = (::ntohl(local_addresses[index]) & 0xff000000) >> 24;
|
||||
|
||||
if (class_1 != 127 && class_1 != 224)
|
||||
{
|
||||
internet_addresses[num_internet_addresses++] = local_addresses[index];
|
||||
local_addresses[index] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Now build the LAN and GameSpy NIC lists. They contain the same entries.
|
||||
// The only difference is that the LAN list puts the non-internet addressable
|
||||
// NIC's first, the GameSpy list puts them last.
|
||||
//
|
||||
NumNics = 0;
|
||||
NumGSNics = 0;
|
||||
|
||||
for (index = 0; index < num_lan_addresses; index++)
|
||||
{
|
||||
NicList[NumNics++] = lan_addresses[index];
|
||||
}
|
||||
|
||||
for (index = 0; index < num_internet_addresses; index++)
|
||||
{
|
||||
NicList[NumNics++] = internet_addresses[index];
|
||||
}
|
||||
|
||||
for (index = 0; index < num_internet_addresses; index++)
|
||||
{
|
||||
GSNicList[NumGSNics++] = internet_addresses[index];
|
||||
}
|
||||
|
||||
for (index = 0; index < num_lan_addresses; index++)
|
||||
{
|
||||
GSNicList[NumGSNics++] = lan_addresses[index];
|
||||
}
|
||||
|
||||
WWASSERT(NumNics == NumGSNics);
|
||||
|
||||
//
|
||||
// Initialize or update PreferredLanNic if required.
|
||||
//
|
||||
bool is_nic_valid = false;
|
||||
for (index = 0; index < NumNics; index++)
|
||||
{
|
||||
if ((ULONG) cUserOptions::PreferredLanNic.Get() == NicList[index])
|
||||
{
|
||||
is_nic_valid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_nic_valid)
|
||||
{
|
||||
if (NumNics > 0)
|
||||
{
|
||||
cUserOptions::PreferredLanNic.Set(NicList[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
cUserOptions::PreferredLanNic.Set(0);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize or update PreferredGameSpyNic if required.
|
||||
//
|
||||
is_nic_valid = false;
|
||||
for (index = 0; index < NumGSNics; index++)
|
||||
{
|
||||
if ((ULONG) cUserOptions::PreferredGameSpyNic.Get() == GSNicList[index])
|
||||
{
|
||||
is_nic_valid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_nic_valid)
|
||||
{
|
||||
if (NumGSNics > 0)
|
||||
{
|
||||
cUserOptions::PreferredGameSpyNic.Set(GSNicList[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
cUserOptions::PreferredGameSpyNic.Set(0);
|
||||
}
|
||||
}
|
||||
|
||||
WWDEBUG_SAY((" PreferredLanNic is %u (%s)\n",
|
||||
(ULONG) cUserOptions::PreferredLanNic.Get(),
|
||||
cNetUtil::Address_To_String(cUserOptions::PreferredLanNic.Get())));
|
||||
|
||||
WWDEBUG_SAY((" PreferredGameSpyNic is %u (%s)\n",
|
||||
(ULONG) cUserOptions::PreferredGameSpyNic.Get(),
|
||||
cNetUtil::Address_To_String(cUserOptions::PreferredGameSpyNic.Get())));
|
||||
|
||||
int cleanup_rc = ::WSACleanup();
|
||||
WWASSERT(cleanup_rc != SOCKET_ERROR);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
ULONG
|
||||
cNicEnum::Enumerate_Nics
|
||||
(
|
||||
ULONG * addresses,
|
||||
ULONG max_nics
|
||||
)
|
||||
{
|
||||
WWASSERT(addresses != NULL);
|
||||
WWASSERT(max_nics > 0);
|
||||
|
||||
WWDEBUG_SAY(("cNicEnum::Enumerate_Nics\n"));
|
||||
|
||||
//
|
||||
// Get the local hostname
|
||||
//
|
||||
char local_host_name[300];
|
||||
int gethostname_rc = ::gethostname(local_host_name, sizeof(local_host_name));
|
||||
WWASSERT(gethostname_rc != SOCKET_ERROR);
|
||||
|
||||
//
|
||||
// Resolve hostname for local adapter addresses.
|
||||
// This does a DNS lookup (name resolution)
|
||||
//
|
||||
LPHOSTENT p_hostent = ::gethostbyname(local_host_name);
|
||||
if (p_hostent == NULL)
|
||||
{
|
||||
DIE;
|
||||
}
|
||||
|
||||
ULONG num_addresses = 0;
|
||||
while (num_addresses < max_nics && p_hostent->h_addr_list[num_addresses] != NULL)
|
||||
{
|
||||
IN_ADDR in_addr;
|
||||
::memcpy(&in_addr, p_hostent->h_addr_list[num_addresses], sizeof(in_addr));
|
||||
addresses[num_addresses] = in_addr.s_addr;
|
||||
WWDEBUG_SAY((" NIC: %s\n", cNetUtil::Address_To_String(addresses[num_addresses])));
|
||||
num_addresses++;
|
||||
}
|
||||
|
||||
return num_addresses;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
void
|
||||
cNicEnum::Init
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
WWDEBUG_SAY(("cNicEnum::Init\n"));
|
||||
|
||||
WSADATA wsa_data;
|
||||
int startup_rc = ::WSAStartup(MAKEWORD(1, 1), &wsa_data);
|
||||
if (startup_rc != 0)
|
||||
{
|
||||
WWDEBUG_SAY((" WSAStartup failed!\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Retrieve list of nic's
|
||||
//
|
||||
ULONG local_addresses[MAX_NICS];
|
||||
ULONG num_addresses = Enumerate_Nics(local_addresses, MAX_NICS);
|
||||
WWASSERT(num_addresses <= MAX_NICS);
|
||||
|
||||
WWDEBUG_SAY((" Found %d NIC(s)\n", num_addresses));
|
||||
|
||||
//
|
||||
// We are going to discard anything that is internet addressable.
|
||||
// The non-internet-addressable NIC's are:
|
||||
// 10.*.*.*
|
||||
// 192.168.*.*
|
||||
// 172.16-31.*.*
|
||||
// We will order these as above to promote the more common choice.
|
||||
//
|
||||
|
||||
USHORT index = 0;
|
||||
USHORT class_1 = 0;
|
||||
USHORT class_2 = 0;
|
||||
NumNics = 0;
|
||||
NumGSNics = 0;
|
||||
|
||||
//
|
||||
// Create a seperate list of GameSpy compatible NIC's that includes
|
||||
// local and internet addressable
|
||||
//
|
||||
// Don't add the following interfaces to the list.
|
||||
// 127.* (localhost)
|
||||
// 224.* (multicast)
|
||||
//
|
||||
for (index = 0; index < num_addresses; index++)
|
||||
{
|
||||
class_1 = (::ntohl(local_addresses[index]) & 0xff000000) >> 24;
|
||||
|
||||
if (class_1 != 127 && class_1 != 224)
|
||||
{
|
||||
GSNicList[NumGSNics++] = local_addresses[index];
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// First, scan for 10.*.*.* addresses
|
||||
//
|
||||
for (index = 0; index < num_addresses; index++)
|
||||
{
|
||||
class_1 = (::ntohl(local_addresses[index]) & 0xff000000) >> 24;
|
||||
|
||||
if (class_1 == 10)
|
||||
{
|
||||
NicList[NumNics++] = local_addresses[index];
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Next, scan for 192.168.*.* addresses
|
||||
//
|
||||
for (index = 0; index < num_addresses; index++)
|
||||
{
|
||||
class_1 = (::ntohl(local_addresses[index]) & 0xff000000) >> 24;
|
||||
class_2 = (::ntohl(local_addresses[index]) & 0x00ff0000) >> 16;
|
||||
|
||||
if (class_1 == 192 && class_2 == 168)
|
||||
{
|
||||
NicList[NumNics++] = local_addresses[index];
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Finally, scan for 172.16-31.*.* addresses
|
||||
//
|
||||
for (index = 0; index < num_addresses; index++)
|
||||
{
|
||||
class_1 = (::ntohl(local_addresses[index]) & 0xff000000) >> 24;
|
||||
class_2 = (::ntohl(local_addresses[index]) & 0x00ff0000) >> 16;
|
||||
|
||||
if (class_1 == 172 && class_2 >= 16 && class_2 <= 31)
|
||||
{
|
||||
NicList[NumNics++] = local_addresses[index];
|
||||
}
|
||||
}
|
||||
|
||||
WWDEBUG_SAY((" Of which %d are non-internet addressable.\n", NumNics));
|
||||
|
||||
//
|
||||
// Initialize or update PreferredLanNic if required.
|
||||
//
|
||||
bool is_nic_valid = false;
|
||||
for (index = 0; index < NumNics; index++)
|
||||
{
|
||||
if ((ULONG) cUserOptions::PreferredLanNic.Get() == NicList[index])
|
||||
{
|
||||
is_nic_valid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_nic_valid)
|
||||
{
|
||||
if (NumNics > 0)
|
||||
{
|
||||
cUserOptions::PreferredLanNic.Set(NicList[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
cUserOptions::PreferredLanNic.Set(0);
|
||||
}
|
||||
}
|
||||
|
||||
is_nic_valid = false;
|
||||
for (index = 0; index < NumGSNics; index++)
|
||||
{
|
||||
if ((ULONG) cUserOptions::PreferredGameSpyNic.Get() == GSNicList[index])
|
||||
{
|
||||
is_nic_valid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_nic_valid)
|
||||
{
|
||||
if (NumGSNics > 0)
|
||||
{
|
||||
cUserOptions::PreferredGameSpyNic.Set(GSNicList[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
cUserOptions::PreferredGameSpyNic.Set(0);
|
||||
}
|
||||
}
|
||||
|
||||
WWDEBUG_SAY((" PreferredLanNic is %u (%s)\n",
|
||||
(ULONG) cUserOptions::PreferredLanNic.Get(),
|
||||
cNetUtil::Address_To_String(cUserOptions::PreferredLanNic.Get())));
|
||||
|
||||
WWDEBUG_SAY((" PreferredGameSpyNic is %u (%s)\n",
|
||||
(ULONG) cUserOptions::PreferredGameSpyNic.Get(),
|
||||
cNetUtil::Address_To_String(cUserOptions::PreferredGameSpyNic.Get())));
|
||||
|
||||
int cleanup_rc = ::WSACleanup();
|
||||
WWASSERT(cleanup_rc != SOCKET_ERROR);
|
||||
}
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user