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