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