Quake-2

Quake 2 GPL Source Release
Log | Files | Refs

g_svcmds.c (6075B)


      1 /*
      2 Copyright (C) 1997-2001 Id Software, Inc.
      3 
      4 This program is free software; you can redistribute it and/or
      5 modify it under the terms of the GNU General Public License
      6 as published by the Free Software Foundation; either version 2
      7 of the License, or (at your option) any later version.
      8 
      9 This program is distributed in the hope that it will be useful,
     10 but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
     12 
     13 See the GNU General Public License for more details.
     14 
     15 You should have received a copy of the GNU General Public License
     16 along with this program; if not, write to the Free Software
     17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     18 
     19 */
     20 
     21 #include "g_local.h"
     22 
     23 
     24 void	Svcmd_Test_f (void)
     25 {
     26 	gi.cprintf (NULL, PRINT_HIGH, "Svcmd_Test_f()\n");
     27 }
     28 
     29 /*
     30 ==============================================================================
     31 
     32 PACKET FILTERING
     33  
     34 
     35 You can add or remove addresses from the filter list with:
     36 
     37 addip <ip>
     38 removeip <ip>
     39 
     40 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".
     41 
     42 Removeip will only remove an address specified exactly the same way.  You cannot addip a subnet, then removeip a single host.
     43 
     44 listip
     45 Prints the current list of filters.
     46 
     47 writeip
     48 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.
     49 
     50 filterban <0 or 1>
     51 
     52 If 1 (the default), then ip addresses matching the current list will be prohibited from entering the game.  This is the default setting.
     53 
     54 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.
     55 
     56 
     57 ==============================================================================
     58 */
     59 
     60 typedef struct
     61 {
     62 	unsigned	mask;
     63 	unsigned	compare;
     64 } ipfilter_t;
     65 
     66 #define	MAX_IPFILTERS	1024
     67 
     68 ipfilter_t	ipfilters[MAX_IPFILTERS];
     69 int			numipfilters;
     70 
     71 /*
     72 =================
     73 StringToFilter
     74 =================
     75 */
     76 static qboolean StringToFilter (char *s, ipfilter_t *f)
     77 {
     78 	char	num[128];
     79 	int		i, j;
     80 	byte	b[4];
     81 	byte	m[4];
     82 	
     83 	for (i=0 ; i<4 ; i++)
     84 	{
     85 		b[i] = 0;
     86 		m[i] = 0;
     87 	}
     88 	
     89 	for (i=0 ; i<4 ; i++)
     90 	{
     91 		if (*s < '0' || *s > '9')
     92 		{
     93 			gi.cprintf(NULL, PRINT_HIGH, "Bad filter address: %s\n", s);
     94 			return false;
     95 		}
     96 		
     97 		j = 0;
     98 		while (*s >= '0' && *s <= '9')
     99 		{
    100 			num[j++] = *s++;
    101 		}
    102 		num[j] = 0;
    103 		b[i] = atoi(num);
    104 		if (b[i] != 0)
    105 			m[i] = 255;
    106 
    107 		if (!*s)
    108 			break;
    109 		s++;
    110 	}
    111 	
    112 	f->mask = *(unsigned *)m;
    113 	f->compare = *(unsigned *)b;
    114 	
    115 	return true;
    116 }
    117 
    118 /*
    119 =================
    120 SV_FilterPacket
    121 =================
    122 */
    123 qboolean SV_FilterPacket (char *from)
    124 {
    125 	int		i;
    126 	unsigned	in;
    127 	byte m[4];
    128 	char *p;
    129 
    130 	i = 0;
    131 	p = from;
    132 	while (*p && i < 4) {
    133 		m[i] = 0;
    134 		while (*p >= '0' && *p <= '9') {
    135 			m[i] = m[i]*10 + (*p - '0');
    136 			p++;
    137 		}
    138 		if (!*p || *p == ':')
    139 			break;
    140 		i++, p++;
    141 	}
    142 	
    143 	in = *(unsigned *)m;
    144 
    145 	for (i=0 ; i<numipfilters ; i++)
    146 		if ( (in & ipfilters[i].mask) == ipfilters[i].compare)
    147 			return (int)filterban->value;
    148 
    149 	return (int)!filterban->value;
    150 }
    151 
    152 
    153 /*
    154 =================
    155 SV_AddIP_f
    156 =================
    157 */
    158 void SVCmd_AddIP_f (void)
    159 {
    160 	int		i;
    161 	
    162 	if (gi.argc() < 3) {
    163 		gi.cprintf(NULL, PRINT_HIGH, "Usage:  addip <ip-mask>\n");
    164 		return;
    165 	}
    166 
    167 	for (i=0 ; i<numipfilters ; i++)
    168 		if (ipfilters[i].compare == 0xffffffff)
    169 			break;		// free spot
    170 	if (i == numipfilters)
    171 	{
    172 		if (numipfilters == MAX_IPFILTERS)
    173 		{
    174 			gi.cprintf (NULL, PRINT_HIGH, "IP filter list is full\n");
    175 			return;
    176 		}
    177 		numipfilters++;
    178 	}
    179 	
    180 	if (!StringToFilter (gi.argv(2), &ipfilters[i]))
    181 		ipfilters[i].compare = 0xffffffff;
    182 }
    183 
    184 /*
    185 =================
    186 SV_RemoveIP_f
    187 =================
    188 */
    189 void SVCmd_RemoveIP_f (void)
    190 {
    191 	ipfilter_t	f;
    192 	int			i, j;
    193 
    194 	if (gi.argc() < 3) {
    195 		gi.cprintf(NULL, PRINT_HIGH, "Usage:  sv removeip <ip-mask>\n");
    196 		return;
    197 	}
    198 
    199 	if (!StringToFilter (gi.argv(2), &f))
    200 		return;
    201 
    202 	for (i=0 ; i<numipfilters ; i++)
    203 		if (ipfilters[i].mask == f.mask
    204 		&& ipfilters[i].compare == f.compare)
    205 		{
    206 			for (j=i+1 ; j<numipfilters ; j++)
    207 				ipfilters[j-1] = ipfilters[j];
    208 			numipfilters--;
    209 			gi.cprintf (NULL, PRINT_HIGH, "Removed.\n");
    210 			return;
    211 		}
    212 	gi.cprintf (NULL, PRINT_HIGH, "Didn't find %s.\n", gi.argv(2));
    213 }
    214 
    215 /*
    216 =================
    217 SV_ListIP_f
    218 =================
    219 */
    220 void SVCmd_ListIP_f (void)
    221 {
    222 	int		i;
    223 	byte	b[4];
    224 
    225 	gi.cprintf (NULL, PRINT_HIGH, "Filter list:\n");
    226 	for (i=0 ; i<numipfilters ; i++)
    227 	{
    228 		*(unsigned *)b = ipfilters[i].compare;
    229 		gi.cprintf (NULL, PRINT_HIGH, "%3i.%3i.%3i.%3i\n", b[0], b[1], b[2], b[3]);
    230 	}
    231 }
    232 
    233 /*
    234 =================
    235 SV_WriteIP_f
    236 =================
    237 */
    238 void SVCmd_WriteIP_f (void)
    239 {
    240 	FILE	*f;
    241 	char	name[MAX_OSPATH];
    242 	byte	b[4];
    243 	int		i;
    244 	cvar_t	*game;
    245 
    246 	game = gi.cvar("game", "", 0);
    247 
    248 	if (!*game->string)
    249 		sprintf (name, "%s/listip.cfg", GAMEVERSION);
    250 	else
    251 		sprintf (name, "%s/listip.cfg", game->string);
    252 
    253 	gi.cprintf (NULL, PRINT_HIGH, "Writing %s.\n", name);
    254 
    255 	f = fopen (name, "wb");
    256 	if (!f)
    257 	{
    258 		gi.cprintf (NULL, PRINT_HIGH, "Couldn't open %s\n", name);
    259 		return;
    260 	}
    261 	
    262 	fprintf(f, "set filterban %d\n", (int)filterban->value);
    263 
    264 	for (i=0 ; i<numipfilters ; i++)
    265 	{
    266 		*(unsigned *)b = ipfilters[i].compare;
    267 		fprintf (f, "sv addip %i.%i.%i.%i\n", b[0], b[1], b[2], b[3]);
    268 	}
    269 	
    270 	fclose (f);
    271 }
    272 
    273 /*
    274 =================
    275 ServerCommand
    276 
    277 ServerCommand will be called when an "sv" command is issued.
    278 The game can issue gi.argc() / gi.argv() commands to get the rest
    279 of the parameters
    280 =================
    281 */
    282 void	ServerCommand (void)
    283 {
    284 	char	*cmd;
    285 
    286 	cmd = gi.argv(1);
    287 	if (Q_stricmp (cmd, "test") == 0)
    288 		Svcmd_Test_f ();
    289 	else if (Q_stricmp (cmd, "addip") == 0)
    290 		SVCmd_AddIP_f ();
    291 	else if (Q_stricmp (cmd, "removeip") == 0)
    292 		SVCmd_RemoveIP_f ();
    293 	else if (Q_stricmp (cmd, "listip") == 0)
    294 		SVCmd_ListIP_f ();
    295 	else if (Q_stricmp (cmd, "writeip") == 0)
    296 		SVCmd_WriteIP_f ();
    297 	else
    298 		gi.cprintf (NULL, PRINT_HIGH, "Unknown server command \"%s\"\n", cmd);
    299 }
    300