mirror of
https://github.com/yquake2/xatrix.git
synced 2025-02-24 04:41:58 +00:00
Clean g_svcmds.c up and add sanity checks
This commit is contained in:
parent
214bd0a6f5
commit
81adfbff59
1 changed files with 207 additions and 155 deletions
306
src/g_svcmds.c
306
src/g_svcmds.c
|
@ -1,42 +1,56 @@
|
||||||
|
/* =======================================================================
|
||||||
|
*
|
||||||
|
* Game side of server CMDs. At this time only the ipfilter.
|
||||||
|
*
|
||||||
|
* =======================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
#include "header/local.h"
|
#include "header/local.h"
|
||||||
|
|
||||||
|
#define MAX_IPFILTERS 1024
|
||||||
|
|
||||||
void Svcmd_Test_f (void)
|
void
|
||||||
|
Svcmd_Test_f(void)
|
||||||
{
|
{
|
||||||
gi.cprintf (NULL, PRINT_HIGH, "Svcmd_Test_f()\n");
|
gi.cprintf(NULL, PRINT_HIGH, "Svcmd_Test_f()\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
==============================================================================
|
* ==============================================================================
|
||||||
|
*
|
||||||
PACKET FILTERING
|
* PACKET FILTERING
|
||||||
|
*
|
||||||
|
*
|
||||||
You can add or remove addresses from the filter list with:
|
* You can add or remove addresses from the filter list with:
|
||||||
|
*
|
||||||
addip <ip>
|
* addip <ip>
|
||||||
removeip <ip>
|
* removeip <ip>
|
||||||
|
*
|
||||||
The ip address is specified in dot format, and any unspecified digits will match any value, so you can specify an entire class C network with "addip 192.246.40".
|
* The ip address is specified in dot format, and any unspecified
|
||||||
|
* digits will match any value, so you can specify an entire class
|
||||||
Removeip will only remove an address specified exactly the same way. You cannot addip a subnet, then removeip a single host.
|
* C network with "addip 192.246.40".
|
||||||
|
*
|
||||||
listip
|
* Removeip will only remove an address specified exactly the same
|
||||||
Prints the current list of filters.
|
* way. You cannot addip a subnet, then removeip a single host.
|
||||||
|
*
|
||||||
writeip
|
* listip
|
||||||
Dumps "addip <ip>" commands to listip.cfg so it can be execed at a later date. The filter lists are not saved and restored by default, because I beleive it would cause too much confusion.
|
* Prints the current list of filters.
|
||||||
|
*
|
||||||
filterban <0 or 1>
|
* writeip
|
||||||
|
* Dumps "addip <ip>" commands to listip.cfg so it can be execed
|
||||||
If 1 (the default), then ip addresses matching the current list will be prohibited from entering the game. This is the default setting.
|
* at a later date. The filter lists are not saved and restored
|
||||||
|
* by default, because I belive it would cause too much confusion.
|
||||||
If 0, then only addresses matching the list will be allowed. This lets you easily set up a private game, or a game that only allows players from your local network.
|
*
|
||||||
|
* filterban <0 or 1>
|
||||||
|
* If 1 (the default), then ip addresses matching the current list
|
||||||
==============================================================================
|
* will be prohibited from entering the game.This is the default
|
||||||
*/
|
* setting.
|
||||||
|
* If 0, then only addresses matching the list will be allowed.
|
||||||
|
* This lets you easily set up a private game, or a game that only
|
||||||
|
* allows players from your local network.
|
||||||
|
*
|
||||||
|
* ==============================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -44,49 +58,56 @@ typedef struct
|
||||||
unsigned compare;
|
unsigned compare;
|
||||||
} ipfilter_t;
|
} ipfilter_t;
|
||||||
|
|
||||||
#define MAX_IPFILTERS 1024
|
|
||||||
|
|
||||||
ipfilter_t ipfilters[MAX_IPFILTERS];
|
ipfilter_t ipfilters[MAX_IPFILTERS];
|
||||||
int numipfilters;
|
int numipfilters;
|
||||||
|
|
||||||
/*
|
qboolean
|
||||||
=================
|
StringToFilter(char *s, ipfilter_t *f)
|
||||||
StringToFilter
|
|
||||||
=================
|
|
||||||
*/
|
|
||||||
qboolean StringToFilter (char *s, ipfilter_t *f)
|
|
||||||
{
|
{
|
||||||
char num[128];
|
char num[128];
|
||||||
int i, j;
|
int i, j;
|
||||||
byte b[4];
|
byte b[4];
|
||||||
byte m[4];
|
byte m[4];
|
||||||
|
|
||||||
for (i=0 ; i<4 ; i++)
|
if (!s || !f)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
b[i] = 0;
|
b[i] = 0;
|
||||||
m[i] = 0;
|
m[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=0 ; i<4 ; i++)
|
for (i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
if (*s < '0' || *s > '9')
|
if ((*s < '0') || (*s > '9'))
|
||||||
{
|
{
|
||||||
gi.cprintf(NULL, PRINT_HIGH, "Bad filter address: %s\n", s);
|
gi.cprintf(NULL, PRINT_HIGH, "Bad filter address: %s\n", s);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
j = 0;
|
j = 0;
|
||||||
|
|
||||||
while (*s >= '0' && *s <= '9')
|
while (*s >= '0' && *s <= '9')
|
||||||
{
|
{
|
||||||
num[j++] = *s++;
|
num[j++] = *s++;
|
||||||
}
|
}
|
||||||
|
|
||||||
num[j] = 0;
|
num[j] = 0;
|
||||||
b[i] = atoi(num);
|
b[i] = atoi(num);
|
||||||
|
|
||||||
if (b[i] != 0)
|
if (b[i] != 0)
|
||||||
|
{
|
||||||
m[i] = 255;
|
m[i] = 255;
|
||||||
|
}
|
||||||
|
|
||||||
if (!*s)
|
if (!*s)
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
s++;
|
s++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,127 +117,143 @@ qboolean StringToFilter (char *s, ipfilter_t *f)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
qboolean
|
||||||
=================
|
SV_FilterPacket(char *from)
|
||||||
SV_FilterPacket
|
|
||||||
=================
|
|
||||||
*/
|
|
||||||
qboolean SV_FilterPacket (char *from)
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
unsigned in;
|
unsigned in;
|
||||||
byte m[4];
|
byte m[4];
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
|
if (!from)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
p = from;
|
p = from;
|
||||||
while (*p && i < 4) {
|
|
||||||
|
while (*p && i < 4)
|
||||||
|
{
|
||||||
m[i] = 0;
|
m[i] = 0;
|
||||||
while (*p >= '0' && *p <= '9') {
|
|
||||||
m[i] = m[i]*10 + (*p - '0');
|
while (*p >= '0' && *p <= '9')
|
||||||
|
{
|
||||||
|
m[i] = m[i] * 10 + (*p - '0');
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
if (!*p || *p == ':')
|
|
||||||
|
if (!*p || (*p == ':'))
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
i++, p++;
|
i++, p++;
|
||||||
}
|
}
|
||||||
|
|
||||||
in = *(unsigned *)m;
|
in = *(unsigned *)m;
|
||||||
|
|
||||||
for (i=0 ; i<numipfilters ; i++)
|
for (i = 0; i < numipfilters; i++)
|
||||||
if ( (in & ipfilters[i].mask) == ipfilters[i].compare)
|
{
|
||||||
|
if ((in & ipfilters[i].mask) == ipfilters[i].compare)
|
||||||
|
{
|
||||||
return (int)filterban->value;
|
return (int)filterban->value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (int)!filterban->value;
|
return (int)!filterban->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
/*
|
SVCmd_AddIP_f(void)
|
||||||
=================
|
|
||||||
SV_AddIP_f
|
|
||||||
=================
|
|
||||||
*/
|
|
||||||
void SVCmd_AddIP_f (void)
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (gi.argc() < 3) {
|
if (gi.argc() < 3)
|
||||||
|
{
|
||||||
gi.cprintf(NULL, PRINT_HIGH, "Usage: addip <ip-mask>\n");
|
gi.cprintf(NULL, PRINT_HIGH, "Usage: addip <ip-mask>\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=0 ; i<numipfilters ; i++)
|
for (i = 0; i < numipfilters; i++)
|
||||||
|
{
|
||||||
if (ipfilters[i].compare == 0xffffffff)
|
if (ipfilters[i].compare == 0xffffffff)
|
||||||
break; // free spot
|
{
|
||||||
|
break; /* free spot */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (i == numipfilters)
|
if (i == numipfilters)
|
||||||
{
|
{
|
||||||
if (numipfilters == MAX_IPFILTERS)
|
if (numipfilters == MAX_IPFILTERS)
|
||||||
{
|
{
|
||||||
gi.cprintf (NULL, PRINT_HIGH, "IP filter list is full\n");
|
gi.cprintf(NULL, PRINT_HIGH, "IP filter list is full\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
numipfilters++;
|
numipfilters++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!StringToFilter (gi.argv(2), &ipfilters[i]))
|
if (!StringToFilter(gi.argv(2), &ipfilters[i]))
|
||||||
|
{
|
||||||
ipfilters[i].compare = 0xffffffff;
|
ipfilters[i].compare = 0xffffffff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
void
|
||||||
=================
|
SVCmd_RemoveIP_f(void)
|
||||||
SV_RemoveIP_f
|
|
||||||
=================
|
|
||||||
*/
|
|
||||||
void SVCmd_RemoveIP_f (void)
|
|
||||||
{
|
{
|
||||||
ipfilter_t f;
|
ipfilter_t f;
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
if (gi.argc() < 3) {
|
if (gi.argc() < 3)
|
||||||
|
{
|
||||||
gi.cprintf(NULL, PRINT_HIGH, "Usage: sv removeip <ip-mask>\n");
|
gi.cprintf(NULL, PRINT_HIGH, "Usage: sv removeip <ip-mask>\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!StringToFilter (gi.argv(2), &f))
|
if (!StringToFilter(gi.argv(2), &f))
|
||||||
return;
|
|
||||||
|
|
||||||
for (i=0 ; i<numipfilters ; i++)
|
|
||||||
if (ipfilters[i].mask == f.mask
|
|
||||||
&& ipfilters[i].compare == f.compare)
|
|
||||||
{
|
{
|
||||||
for (j=i+1 ; j<numipfilters ; j++)
|
|
||||||
ipfilters[j-1] = ipfilters[j];
|
|
||||||
numipfilters--;
|
|
||||||
gi.cprintf (NULL, PRINT_HIGH, "Removed.\n");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
gi.cprintf (NULL, PRINT_HIGH, "Didn't find %s.\n", gi.argv(2));
|
|
||||||
|
for (i = 0; i < numipfilters; i++)
|
||||||
|
{
|
||||||
|
if ((ipfilters[i].mask == f.mask) &&
|
||||||
|
(ipfilters[i].compare == f.compare))
|
||||||
|
{
|
||||||
|
for (j = i + 1; j < numipfilters; j++)
|
||||||
|
{
|
||||||
|
ipfilters[j - 1] = ipfilters[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
numipfilters--;
|
||||||
|
gi.cprintf(NULL, PRINT_HIGH, "Removed.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gi.cprintf(NULL, PRINT_HIGH, "Didn't find %s.\n", gi.argv(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
void
|
||||||
=================
|
SVCmd_ListIP_f(void)
|
||||||
SV_ListIP_f
|
|
||||||
=================
|
|
||||||
*/
|
|
||||||
void SVCmd_ListIP_f (void)
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
byte b[4];
|
byte b[4];
|
||||||
|
|
||||||
gi.cprintf (NULL, PRINT_HIGH, "Filter list:\n");
|
gi.cprintf(NULL, PRINT_HIGH, "Filter list:\n");
|
||||||
for (i=0 ; i<numipfilters ; i++)
|
|
||||||
|
for (i = 0; i < numipfilters; i++)
|
||||||
{
|
{
|
||||||
*(unsigned *)b = ipfilters[i].compare;
|
*(unsigned *)b = ipfilters[i].compare;
|
||||||
gi.cprintf (NULL, PRINT_HIGH, "%3i.%3i.%3i.%3i\n", b[0], b[1], b[2], b[3]);
|
gi.cprintf(NULL, PRINT_HIGH, "%3i.%3i.%3i.%3i\n",
|
||||||
|
b[0], b[1], b[2], b[3]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
void
|
||||||
=================
|
SVCmd_WriteIP_f(void)
|
||||||
SV_WriteIP_f
|
|
||||||
=================
|
|
||||||
*/
|
|
||||||
void SVCmd_WriteIP_f (void)
|
|
||||||
{
|
{
|
||||||
FILE *f;
|
FILE *f;
|
||||||
char name[MAX_OSPATH];
|
char name[MAX_OSPATH];
|
||||||
|
@ -227,55 +264,70 @@ void SVCmd_WriteIP_f (void)
|
||||||
game = gi.cvar("game", "", 0);
|
game = gi.cvar("game", "", 0);
|
||||||
|
|
||||||
if (!*game->string)
|
if (!*game->string)
|
||||||
sprintf (name, "%s/listip.cfg", GAMEVERSION);
|
{
|
||||||
|
sprintf(name, "%s/listip.cfg", GAMEVERSION);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
sprintf (name, "%s/listip.cfg", game->string);
|
{
|
||||||
|
sprintf(name, "%s/listip.cfg", game->string);
|
||||||
|
}
|
||||||
|
|
||||||
gi.cprintf (NULL, PRINT_HIGH, "Writing %s.\n", name);
|
gi.cprintf(NULL, PRINT_HIGH, "Writing %s.\n", name);
|
||||||
|
|
||||||
|
f = fopen(name, "wb");
|
||||||
|
|
||||||
f = fopen (name, "wb");
|
|
||||||
if (!f)
|
if (!f)
|
||||||
{
|
{
|
||||||
gi.cprintf (NULL, PRINT_HIGH, "Couldn't open %s\n", name);
|
gi.cprintf(NULL, PRINT_HIGH, "Couldn't open %s\n", name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(f, "set filterban %d\n", (int)filterban->value);
|
fprintf(f, "set filterban %d\n", (int)filterban->value);
|
||||||
|
|
||||||
for (i=0 ; i<numipfilters ; i++)
|
for (i = 0; i < numipfilters; i++)
|
||||||
{
|
{
|
||||||
*(unsigned *)b = ipfilters[i].compare;
|
*(unsigned *)b = ipfilters[i].compare;
|
||||||
fprintf (f, "sv addip %i.%i.%i.%i\n", b[0], b[1], b[2], b[3]);
|
fprintf(f, "sv addip %i.%i.%i.%i\n", b[0], b[1], b[2], b[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose (f);
|
fclose(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
=================
|
* ServerCommand will be called when an "sv" command is issued.
|
||||||
ServerCommand
|
* The game can issue gi.argc() / gi.argv() commands to get the rest
|
||||||
|
* of the parameters
|
||||||
ServerCommand will be called when an "sv" command is issued.
|
*/
|
||||||
The game can issue gi.argc() / gi.argv() commands to get the rest
|
void
|
||||||
of the parameters
|
ServerCommand(void)
|
||||||
=================
|
|
||||||
*/
|
|
||||||
void ServerCommand (void)
|
|
||||||
{
|
{
|
||||||
char *cmd;
|
char *cmd;
|
||||||
|
|
||||||
cmd = gi.argv(1);
|
cmd = gi.argv(1);
|
||||||
if (Q_stricmp (cmd, "test") == 0)
|
|
||||||
Svcmd_Test_f ();
|
if (Q_stricmp(cmd, "test") == 0)
|
||||||
else if (Q_stricmp (cmd, "addip") == 0)
|
{
|
||||||
SVCmd_AddIP_f ();
|
Svcmd_Test_f();
|
||||||
else if (Q_stricmp (cmd, "removeip") == 0)
|
}
|
||||||
SVCmd_RemoveIP_f ();
|
else if (Q_stricmp(cmd, "addip") == 0)
|
||||||
else if (Q_stricmp (cmd, "listip") == 0)
|
{
|
||||||
SVCmd_ListIP_f ();
|
SVCmd_AddIP_f();
|
||||||
else if (Q_stricmp (cmd, "writeip") == 0)
|
}
|
||||||
SVCmd_WriteIP_f ();
|
else if (Q_stricmp(cmd, "removeip") == 0)
|
||||||
|
{
|
||||||
|
SVCmd_RemoveIP_f();
|
||||||
|
}
|
||||||
|
else if (Q_stricmp(cmd, "listip") == 0)
|
||||||
|
{
|
||||||
|
SVCmd_ListIP_f();
|
||||||
|
}
|
||||||
|
else if (Q_stricmp(cmd, "writeip") == 0)
|
||||||
|
{
|
||||||
|
SVCmd_WriteIP_f();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
gi.cprintf (NULL, PRINT_HIGH, "Unknown server command \"%s\"\n", cmd);
|
{
|
||||||
|
gi.cprintf(NULL, PRINT_HIGH, "Unknown server command \"%s\"\n", cmd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue