This repository has been archived on 2025-02-27. You can view files and clone it, but cannot push or open issues or pull requests.
CnC_Renegade/Code/Tests/Bandy/bandy.cpp

341 lines
No EOL
9.5 KiB
C++

/*
** 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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Bandwidth Tester Tester *
* *
* $Archive:: /Commando/Code/Tests/Bandy/bandy.cpp $*
* *
* $Author:: Steve_t $*
* *
* $Modtime:: 1/05/02 10:22p $*
* *
* $Revision:: 4 $*
* *
* *
*---------------------------------------------------------------------------------------------*
* *
* *
*---------------------------------------------------------------------------------------------*
* *
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include <winsock.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <bandtest\bandtest.h>
char *ErrorList[13] = {
"BANDTEST_OK",
"BANDTEST_NO_WINSOCK2",
"BANDTEST_NO_RAW_SOCKET_PERMISSION",
"BANDTEST_NO_RAW_SOCKET_CREATE",
"BANDTEST_NO_UDP_SOCKET_BIND",
"BANDTEST_NO_TTL_SET",
"BANDTEST_NO_PING_RESPONSE",
"BANDTEST_NO_FINAL_PING_TIME",
"BANDTEST_NO_EXTERNAL_ROUTER",
"BANDTEST_NO_IP_DETECT",
"BANDTEST_UNKNOWN_ERROR",
"BANDTEST_WRONG_API_VERSION",
"BANDTEST_BAD_PARAM"
};
#define NUM_BANDS 12
unsigned long Bandwidths [NUM_BANDS * 2] = {
12000, 14400,
25000, 28800,
33600, 33600,
53000, 57600,
62000, 67200,
105000, 115200,
125000, 128000,
250000, 256000,
500000, 512000,
999999, 1024000,
1999999, 2048000,
3999999, 4096000
};
char *BandwidthNames [NUM_BANDS] = {
"14400",
"28800",
"33600",
"57600",
"67200",
"115200",
"128k",
"256k",
"512k",
"1M",
"2M",
"4M"
};
BandtestSettingsStruct DefaultSettings = {
0, //AlwaysICMP
0, //TTLScatter
50, //FastPingPackets
12, //SlowPingPackets
25, //def =
0, //Ping profile
};
ULONG Enumerate_Nics(ULONG * addresses, ULONG max_nics)
{
assert(addresses != NULL);
assert(max_nics > 0);
ULONG num_addresses = 0;
//
// Get the local hostname
//
char local_host_name[300];
#ifdef _DEBUG
int gethostname_rc =
#endif //DEBUG
gethostname(local_host_name, sizeof(local_host_name));
assert(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)
{
}
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;
num_addresses++;
}
return num_addresses;
}
char * Addr_As_String(unsigned char *addr)
{
static char _string[128];
sprintf(_string, "%d.%d.%d.%d", (int)(addr[0]), (int)(addr[1]), (int)(addr[2]), (int)(addr[3]));
return(_string);
}
int main(int argc, char **argv)
{
unsigned long my_addresses[8];
int use_addr = -1;
int retries = 3;
int failure_code = BANDTEST_OK;
struct sockaddr_in address;
BandtestSettingsStruct *settings = &DefaultSettings;
WSADATA wsa_data;
if (WSAStartup(MAKEWORD(1,1), &wsa_data) != 0) {
printf("Bandy: WSAStartup failed: error code %d\n", GetLastError());
return(0);
}
int nics = Enumerate_Nics(&my_addresses[0], 8);
struct hostent *host = gethostbyname("www.ea.com");
/*
** Usage.
*/
printf("Bandwidth tester tester\n");
printf("Programmer: Steve Tall\n");
printf("V1.0\n");
printf("Usage: bandy.exe <options>\n");
printf("Options:\n");
printf(" -s<server> - Use specified server (def = www.ea.com)\n");
printf(" -i<ip index> - Use specified local ip index (def = auto discovery)\n");
printf(" -r<retrys> - Retry attempts after failure (def = 3)\n");
printf(" -l<packets> - Number of packets to send on low ping times (def = 50)\n");
printf(" -h<packets> - Number of packets to send on high ping times (def = 12)\n");
printf(" -p<time> - Fast ping threshold in ms (def = 25 ms)\n");
printf(" -a - Send bulk data as ICMP packets (def = UDP)\n");
printf(" -t - Scatter TTL on bulk data (def = no TTL scatter)\n");
printf(" -x - Do ping profiling (def = no profiling)\n\n");
printf("Available IPs : ");
for (int i=0 ; i<nics ; i++) {
printf("%d - %s\n ", i, Addr_As_String((unsigned char*)&my_addresses[i]));
}
printf("\n");
//WSACleanup();
//return(0);
for (int a=1 ; a<argc ; a++) {
if (argv[a][0] != '-' || strlen(&argv[a][0]) < 2) {
printf("Bad parameter %d\n", a);
WSACleanup();
return(0);
}
switch (toupper(argv[a][1])) {
case 'S':
host = gethostbyname(&argv[a][2]);
if (host == NULL) {
printf("Unable to resolve host name %s\n", &argv[a][2]);
WSACleanup();
return(0);
}
break;
case 'I':
use_addr = atoi(&argv[a][2]);
if (use_addr >= nics) {
printf("Bad IP index\n");
WSACleanup();
return(0);
}
break;
case 'R':
retries = atoi(&argv[a][2]);
break;
case 'L':
settings->FastPingPackets = atoi(&argv[a][2]);
break;
case 'H':
settings->SlowPingPackets = atoi(&argv[a][2]);
break;
case 'P':
settings->FastPingThreshold = atoi(&argv[a][2]);
break;
case 'A':
settings->AlwaysICMP = 1;
break;
case 'T':
settings->TTLScatter = 1;
break;
case 'X':
settings->PingProfile = 1;
break;
case 0:
default:
printf("Bad parameter %d\n", a);
WSACleanup();
return(0);
}
}
if (host == NULL) {
printf("Unable to resolve host name\n");
WSACleanup();
return(0);
}
memcpy(&(address.sin_addr), host->h_addr, host->h_length);
printf("Detecting bandwidth - please wait\n");
unsigned long downstream = 0;
unsigned long bw = Detect_Bandwidth(ntohl(address.sin_addr.s_addr), (use_addr == -1) ? 0 : ntohl(my_addresses[use_addr]), retries, failure_code, downstream, BANDTEST_API_VERSION, settings);
if (bw == 0) {
printf("Failed to get bandwidth - error code %s\n", ErrorList[failure_code]);
} else {
if (bw == 0xffffffff) {
printf("Upstream bandwidth is huge :-)\n");
} else {
if (bw > 100000) {
float floater = (float)bw / 1024;
printf("Upstream bandwidth to external router is %.1f kilobits per second\n", floater);
} else {
printf("Upstream bandwidth to external router is %d bits per second\n", bw);
}
bool got_bw_str = false;
for (int i=0 ; i<NUM_BANDS ; i++) {
if (bw < Bandwidths[i*2]) {
printf("Reported upstream connection bandwidth is %s bits per second\n", BandwidthNames[i]);
got_bw_str = true;
break;
}
}
if (!got_bw_str) {
printf("Reported upstream connection bandwidth is > 4M bits per second\n");
}
}
printf("\n");
if (downstream == 0xffffffff) {
printf("Downstream bandwidth is huge :-)\n");
} else {
if (downstream > 100000) {
float floater = (float)downstream / 1024;
printf("Downstream bandwidth to external router is %.1f kilobits per second\n", floater);
} else {
printf("Downstream bandwidth to external router is %d bits per second\n", downstream);
}
bool got_downstream_str = false;
for (int i=0 ; i<NUM_BANDS ; i++) {
if (downstream < Bandwidths[i*2]) {
printf("Reported downstream connection bandwidth is %s bits per second\n", BandwidthNames[i]);
got_downstream_str = true;
break;
}
}
if (!got_downstream_str) {
printf("Reported downstream connection bandwidth is > 4M bits per second\n");
}
}
}
WSACleanup();
return(0);
}