bug fixes to ban logic, partial ipv4 addresses work for bans, ban with reasons (ex. ban 192.168.0.0/16 "I hate people on LANs"), addip/removeip/listip can use the same format as ban (and now work for ipv6/ipx), writeip removed and will be fixed/replaced later
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@2295 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
c19474d271
commit
116faaf0c9
5 changed files with 275 additions and 191 deletions
|
@ -580,7 +580,7 @@ qboolean NET_StringToAdr (char *s, netadr_t *a)
|
|||
// (bits < 0 will always fill all bits)
|
||||
void NET_IntegerToMask (netadr_t *a, netadr_t *amask, int bits)
|
||||
{
|
||||
int i;
|
||||
unsigned int i;
|
||||
qbyte *n;
|
||||
|
||||
memset (amask, 0, sizeof(*amask));
|
||||
|
@ -608,7 +608,8 @@ void NET_IntegerToMask (netadr_t *a, netadr_t *amask, int bits)
|
|||
// fill last bit
|
||||
if (i)
|
||||
{
|
||||
i = (~((1 << i) - 1)) & 0xFF;
|
||||
i = 8 - i;
|
||||
i = 255 - ((1 << i) - 1);
|
||||
*n = i;
|
||||
}
|
||||
break;
|
||||
|
@ -628,7 +629,8 @@ void NET_IntegerToMask (netadr_t *a, netadr_t *amask, int bits)
|
|||
// fill last bit
|
||||
if (i)
|
||||
{
|
||||
i = (~((1 << i) - 1)) & 0xFF;
|
||||
i = 8 - i;
|
||||
i = 255 - ((1 << i) - 1);
|
||||
*n = i;
|
||||
}
|
||||
break;
|
||||
|
@ -647,13 +649,62 @@ void NET_IntegerToMask (netadr_t *a, netadr_t *amask, int bits)
|
|||
// fill last bit
|
||||
if (i)
|
||||
{
|
||||
i = (~((1 << i) - 1)) & 0xFF;
|
||||
i = 8 - i;
|
||||
i = 255 - ((1 << i) - 1);
|
||||
*n = i;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// ParsePartialIPv4: check string to see if it is a partial IPv4 address and
|
||||
// return bits to mask and set netadr_t or 0 if not an address
|
||||
int ParsePartialIPv4(char *s, netadr_t *a)
|
||||
{
|
||||
char *colon = NULL;
|
||||
char *address = a->address.ip;
|
||||
int bits = 8;
|
||||
|
||||
if (!*s)
|
||||
return 0;
|
||||
|
||||
memset (a, 0, sizeof(*a));
|
||||
while (*s)
|
||||
{
|
||||
if (*s == ':')
|
||||
{
|
||||
if (colon) // only 1 colon
|
||||
return 0;
|
||||
colon = s + 1;
|
||||
}
|
||||
else if (*s == '.')
|
||||
{
|
||||
if (colon) // no colons before periods (probably invalid anyway)
|
||||
return 0;
|
||||
else if (bits >= 32) // only 32 bits in ipv4
|
||||
return 0;
|
||||
else if (*(s+1) == '.')
|
||||
return 0;
|
||||
else if (*(s+1) == '\0')
|
||||
break; // don't add more bits to the mask for x.x., etc
|
||||
bits += 8;
|
||||
address++;
|
||||
}
|
||||
else if (*s >= '0' && *s <= '9')
|
||||
*address = ((*address)*10) + (*s-'0');
|
||||
else
|
||||
return 0; // invalid character
|
||||
|
||||
s++;
|
||||
}
|
||||
|
||||
a->type = NA_IP;
|
||||
if (colon)
|
||||
a->port = atoi(colon);
|
||||
|
||||
return bits;
|
||||
}
|
||||
|
||||
// NET_StringToAdrMasked: extension to NET_StringToAdr to handle IP addresses
|
||||
// with masks or integers representing the bit masks
|
||||
qboolean NET_StringToAdrMasked (char *s, netadr_t *a, netadr_t *amask)
|
||||
|
@ -669,12 +720,12 @@ qboolean NET_StringToAdrMasked (char *s, netadr_t *a, netadr_t *amask)
|
|||
// we have a slash in the address so split and resolve separately
|
||||
char *c;
|
||||
|
||||
i = spoint - s;
|
||||
if (i + 1 > sizeof(t))
|
||||
i = (int)(spoint - s) + 1;
|
||||
if (i > sizeof(t))
|
||||
i = sizeof(t);
|
||||
|
||||
Q_strncpyz(t, s, i);
|
||||
if (!NET_StringToAdr(t, a))
|
||||
if (!ParsePartialIPv4(t, a) && !NET_StringToAdr(t, a))
|
||||
return false;
|
||||
spoint++;
|
||||
|
||||
|
@ -693,7 +744,7 @@ qboolean NET_StringToAdrMasked (char *s, netadr_t *a, netadr_t *amask)
|
|||
}
|
||||
|
||||
if (c == NULL) // we have an address so resolve it and return
|
||||
return NET_StringToAdr(spoint, amask);
|
||||
return ParsePartialIPv4(spoint, amask) || NET_StringToAdr(spoint, amask);
|
||||
|
||||
// otherwise generate mask for given bits
|
||||
i = atoi(spoint);
|
||||
|
@ -702,13 +753,17 @@ qboolean NET_StringToAdrMasked (char *s, netadr_t *a, netadr_t *amask)
|
|||
else
|
||||
{
|
||||
// we don't have a slash, resolve and fill with a full mask
|
||||
if (!NET_StringToAdr(s, a))
|
||||
i = ParsePartialIPv4(s, a);
|
||||
if (!i && !NET_StringToAdr(s, a))
|
||||
return false;
|
||||
|
||||
memset (amask, 0, sizeof(*amask));
|
||||
amask->type = a->type;
|
||||
|
||||
NET_IntegerToMask(a, amask, -1);
|
||||
if (i)
|
||||
NET_IntegerToMask(a, amask, i);
|
||||
else
|
||||
NET_IntegerToMask(a, amask, -1);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -774,7 +829,7 @@ int UniformMaskedBits(netadr_t mask)
|
|||
{
|
||||
int bits;
|
||||
int b;
|
||||
int bs;
|
||||
unsigned int bs;
|
||||
qboolean bitenc = false;
|
||||
|
||||
switch (mask.type)
|
||||
|
@ -788,7 +843,7 @@ int UniformMaskedBits(netadr_t mask)
|
|||
bitenc = true;
|
||||
else if (mask.address.ip[b])
|
||||
{
|
||||
bs = ~mask.address.ip[b];
|
||||
bs = (~mask.address.ip[b]) & 0xFF;
|
||||
while (bs)
|
||||
{
|
||||
if (bs & 1)
|
||||
|
@ -818,7 +873,7 @@ int UniformMaskedBits(netadr_t mask)
|
|||
bitenc = true;
|
||||
else if (mask.address.ip6[b])
|
||||
{
|
||||
bs = ~mask.address.ip6[b];
|
||||
bs = (~mask.address.ip6[b]) & 0xFF;
|
||||
while (bs)
|
||||
{
|
||||
if (bs & 1)
|
||||
|
@ -849,7 +904,7 @@ int UniformMaskedBits(netadr_t mask)
|
|||
bitenc = true;
|
||||
else if (mask.address.ipx[b])
|
||||
{
|
||||
bs = ~mask.address.ipx[b];
|
||||
bs = (~mask.address.ipx[b]) & 0xFF;
|
||||
while (bs)
|
||||
{
|
||||
if (bs & 1)
|
||||
|
@ -887,7 +942,13 @@ char *NET_AdrToStringMasked (netadr_t a, netadr_t amask)
|
|||
if (i >= 0)
|
||||
sprintf(s, "%s/%i", NET_AdrToString(a), i);
|
||||
else
|
||||
sprintf(s, "%s/%s", NET_AdrToString(a), NET_AdrToString(amask));
|
||||
{
|
||||
// has to be done this way due to NET_AdrToString returning a
|
||||
// static address
|
||||
Q_strncatz(s, NET_AdrToString(a), sizeof(s));
|
||||
Q_strncatz(s, "/", sizeof(s));
|
||||
Q_strncatz(s, NET_AdrToString(amask), sizeof(s));
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
|
|
@ -651,8 +651,15 @@ typedef struct bannedips_s {
|
|||
struct bannedips_s *next;
|
||||
netadr_t adr;
|
||||
netadr_t adrmask;
|
||||
char reason[1];
|
||||
} bannedips_t;
|
||||
|
||||
typedef struct filteredip_s {
|
||||
struct filteredip_s *next;
|
||||
netadr_t adr;
|
||||
netadr_t adrmask;
|
||||
} filteredips_t;
|
||||
|
||||
typedef enum {
|
||||
GT_PROGS, //q1, qw, h2 are similar enough that we consider it only one game mode. (We don't support the h2 protocol)
|
||||
GT_QUAKE2, //q2 servers run from a q2 game dll
|
||||
|
@ -711,6 +718,7 @@ typedef struct
|
|||
challenge_t challenges[MAX_CHALLENGES]; // to prevent invalid IPs from connecting
|
||||
|
||||
bannedips_t *bannedips;
|
||||
filteredips_t *filteredips;
|
||||
|
||||
char progsnames[MAX_PROGS][32];
|
||||
progsnum_t progsnum[MAX_PROGS];
|
||||
|
|
|
@ -638,13 +638,21 @@ void SV_BanName_f (void)
|
|||
{
|
||||
client_t *cl;
|
||||
int clnum=-1;
|
||||
char *reason = NULL;
|
||||
int reasonsize = 0;
|
||||
|
||||
if (Cmd_Argc() < 2)
|
||||
{
|
||||
Con_Printf("%s userid|nick\n", Cmd_Argv(0));
|
||||
Con_Printf("%s userid|nick [reason]\n", Cmd_Argv(0));
|
||||
return;
|
||||
}
|
||||
|
||||
if (Cmd_Argc() > 2)
|
||||
{
|
||||
reason = Cmd_Argv(2);
|
||||
reasonsize = strlen(reason);
|
||||
}
|
||||
|
||||
while((cl = SV_GetClientForString(Cmd_Argv(1), &clnum)))
|
||||
if (cl)
|
||||
{
|
||||
|
@ -656,13 +664,15 @@ void SV_BanName_f (void)
|
|||
continue;
|
||||
}
|
||||
|
||||
nb = Z_Malloc(sizeof(bannedips_t));
|
||||
nb = Z_Malloc(sizeof(bannedips_t)+reasonsize);
|
||||
nb->next = svs.bannedips;
|
||||
nb->adr = cl->netchan.remote_address;
|
||||
NET_IntegerToMask(&nb->adr, &nb->adrmask, -1); // fill mask
|
||||
if (*Cmd_Argv(2)) //explicit blocking of all ports of a client ip
|
||||
nb->adr.port = 0;
|
||||
svs.bannedips = nb;
|
||||
if (reasonsize)
|
||||
Q_strcpy(nb->reason, reason);
|
||||
|
||||
SV_BroadcastTPrintf (PRINT_HIGH, STL_CLIENTWASBANNED, cl->name);
|
||||
// print directly, because the dropped client won't get the
|
||||
|
@ -682,10 +692,12 @@ void SV_BanIP_f (void)
|
|||
int i;
|
||||
client_t *cl;
|
||||
bannedips_t *nb;
|
||||
char *reason = NULL;
|
||||
int reasonsize = 0;
|
||||
|
||||
if (Cmd_Argc() < 2)
|
||||
{
|
||||
Con_Printf("%s address/mask|adress/maskbits\n", Cmd_Argv(0));
|
||||
Con_Printf("%s address/mask|adress/maskbits [reason]\n", Cmd_Argv(0));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -701,6 +713,12 @@ void SV_BanIP_f (void)
|
|||
return;
|
||||
}
|
||||
|
||||
if (Cmd_Argc() > 2)
|
||||
{
|
||||
reason = Cmd_Argv(2);
|
||||
reasonsize = strlen(reason);
|
||||
}
|
||||
|
||||
// loop through clients and kick the ones that match
|
||||
for (i = 0, cl = svs.clients; i < sv.allocated_client_slots; i++, cl++)
|
||||
{
|
||||
|
@ -719,11 +737,58 @@ void SV_BanIP_f (void)
|
|||
}
|
||||
|
||||
// add IP and mask to ban list
|
||||
nb = Z_Malloc(sizeof(bannedips_t));
|
||||
nb = Z_Malloc(sizeof(bannedips_t)+reasonsize);
|
||||
nb->next = svs.bannedips;
|
||||
nb->adr = banadr;
|
||||
nb->adrmask = banmask;
|
||||
svs.bannedips = nb;
|
||||
if (reasonsize)
|
||||
Q_strcpy(nb->reason, reason);
|
||||
}
|
||||
|
||||
void SV_FilterIP_f (void)
|
||||
{
|
||||
netadr_t banadr;
|
||||
netadr_t banmask;
|
||||
int i;
|
||||
client_t *cl;
|
||||
filteredips_t *nb;
|
||||
extern cvar_t filterban;
|
||||
|
||||
if (Cmd_Argc() < 2)
|
||||
{
|
||||
Con_Printf("%s address/mask|adress/maskbits\n", Cmd_Argv(0));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!NET_StringToAdrMasked(Cmd_Argv(1), &banadr, &banmask))
|
||||
{
|
||||
Con_Printf("invalid address or mask\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (NET_IsLoopBackAddress(banadr))
|
||||
{
|
||||
Con_Printf("You're not allowed to filter loopback!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// loop through clients and kick the ones that match
|
||||
for (i = 0, cl = svs.clients; i < sv.allocated_client_slots; i++, cl++)
|
||||
{
|
||||
if (cl->state<=cs_zombie)
|
||||
continue;
|
||||
|
||||
if (filterban.value && NET_CompareAdrMasked(cl->netchan.remote_address, banadr, banmask))
|
||||
SV_DropClient (cl);
|
||||
}
|
||||
|
||||
// add IP and mask to filter list
|
||||
nb = Z_Malloc(sizeof(filteredips_t));
|
||||
nb->next = svs.filteredips;
|
||||
nb->adr = banadr;
|
||||
nb->adrmask = banmask;
|
||||
svs.filteredips = nb;
|
||||
}
|
||||
|
||||
void SV_BanList_f (void)
|
||||
|
@ -733,7 +798,10 @@ void SV_BanList_f (void)
|
|||
|
||||
while (nb)
|
||||
{
|
||||
Con_Printf("%s\n", NET_AdrToStringMasked(nb->adr, nb->adrmask));
|
||||
if (nb->reason[0])
|
||||
Con_Printf("%s, %s\n", NET_AdrToStringMasked(nb->adr, nb->adrmask), nb->reason);
|
||||
else
|
||||
Con_Printf("%s\n", NET_AdrToStringMasked(nb->adr, nb->adrmask));
|
||||
bancount++;
|
||||
nb = nb->next;
|
||||
}
|
||||
|
@ -741,6 +809,21 @@ void SV_BanList_f (void)
|
|||
Con_Printf("%i total entries in ban list\n", bancount);
|
||||
}
|
||||
|
||||
void SV_FilterList_f (void)
|
||||
{
|
||||
int filtercount = 0;
|
||||
filteredips_t *nb = svs.filteredips;
|
||||
|
||||
while (nb)
|
||||
{
|
||||
Con_Printf("%s\n", NET_AdrToStringMasked(nb->adr, nb->adrmask));
|
||||
filtercount++;
|
||||
nb = nb->next;
|
||||
}
|
||||
|
||||
Con_Printf("%i total entries in filter list\n", filtercount);
|
||||
}
|
||||
|
||||
void SV_Unban_f (void)
|
||||
{
|
||||
qboolean all = false;
|
||||
|
@ -766,7 +849,7 @@ void SV_Unban_f (void)
|
|||
while (nb)
|
||||
{
|
||||
nbnext = nb->next;
|
||||
if (NET_CompareAdrMasked(nb->adr, unbanadr, unbanmask))
|
||||
if (all || NET_CompareAdrMasked(nb->adr, unbanadr, unbanmask))
|
||||
{
|
||||
if (!all)
|
||||
Con_Printf("unbanned %s\n", NET_AdrToStringMasked(nb->adr, nb->adrmask));
|
||||
|
@ -779,6 +862,44 @@ void SV_Unban_f (void)
|
|||
}
|
||||
}
|
||||
|
||||
void SV_Unfilter_f (void)
|
||||
{
|
||||
qboolean all = false;
|
||||
filteredips_t *nb = svs.filteredips;
|
||||
filteredips_t *nbnext;
|
||||
netadr_t unbanadr = {0};
|
||||
netadr_t unbanmask = {0};
|
||||
|
||||
if (Cmd_Argc() < 2)
|
||||
{
|
||||
Con_Printf("%s address/mask|address/maskbits|all\n", Cmd_Argv(0));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Q_strcasecmp(Cmd_Argv(1), "all"))
|
||||
all = true;
|
||||
else if (!NET_StringToAdrMasked(Cmd_Argv(1), &unbanadr, &unbanmask))
|
||||
{
|
||||
Con_Printf("invalid address or mask\n");
|
||||
return;
|
||||
}
|
||||
|
||||
while (nb)
|
||||
{
|
||||
nbnext = nb->next;
|
||||
if (all || NET_CompareAdrMasked(nb->adr, unbanadr, unbanmask))
|
||||
{
|
||||
if (!all)
|
||||
Con_Printf("unfiltered %s\n", NET_AdrToStringMasked(nb->adr, nb->adrmask));
|
||||
if (svs.filteredips == nb)
|
||||
svs.filteredips = nbnext;
|
||||
Z_Free(nb);
|
||||
}
|
||||
|
||||
nb = nbnext;
|
||||
}
|
||||
}
|
||||
|
||||
void SV_ForceName_f (void)
|
||||
{
|
||||
client_t *cl;
|
||||
|
@ -1807,6 +1928,16 @@ void SV_InitOperatorCommands (void)
|
|||
// Cmd_AddCommand ("ban", SV_BanName_f);
|
||||
Cmd_AddCommand ("status", SV_Status_f);
|
||||
|
||||
Cmd_AddCommand ("addip", SV_FilterIP_f);
|
||||
Cmd_AddCommand ("removeip", SV_Unfilter_f);
|
||||
Cmd_AddCommand ("listip", SV_FilterList_f);
|
||||
|
||||
// Cmd_AddCommand ("filterip", SV_FilterIP_f);
|
||||
// Cmd_AddCommand ("unfilter", SV_Unfilter_f);
|
||||
// Cmd_AddCommand ("filterlist", SV_FilterList_f);
|
||||
|
||||
// Cmd_AddCommand ("writeip", SV_WriteIP_f);
|
||||
|
||||
Cmd_AddCommand ("sv", SV_SendGameCommand_f);
|
||||
|
||||
Cmd_AddCommand ("killserver", SV_KillServer_f);
|
||||
|
|
|
@ -196,6 +196,7 @@ void SV_FixupName(char *in, char *out);
|
|||
void SV_AcceptClient (netadr_t adr, int userid, char *userinfo);
|
||||
void Master_Shutdown (void);
|
||||
void PR_SetPlayerClass(client_t *cl, int classnum, qboolean fromqc);
|
||||
bannedips_t *SV_BannedAddress (netadr_t *a);
|
||||
|
||||
//============================================================================
|
||||
|
||||
|
@ -1757,18 +1758,16 @@ client_t *SVC_DirectConnect(void)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
bannedips_t *banip;
|
||||
for (banip = svs.bannedips; banip; banip=banip->next)
|
||||
bannedips_t *banip = SV_BannedAddress(&adr);
|
||||
if (banip)
|
||||
{
|
||||
if (NET_CompareAdrMasked(adr, banip->adr, banip->adrmask))
|
||||
{
|
||||
SV_RejectMessage (protocol, "You were banned.\nContact the administrator to complain.\n");
|
||||
return NULL;
|
||||
}
|
||||
if (banip->reason[0])
|
||||
SV_RejectMessage (protocol, "You were banned.\nReason: %s\n", banip->reason);
|
||||
else
|
||||
SV_RejectMessage (protocol, "You were banned.\n");
|
||||
return NULL;
|
||||
}
|
||||
//yay, a legit client who we havn't banned yet.
|
||||
}
|
||||
|
||||
edictnum = (newcl-svs.clients)+1;
|
||||
|
@ -2091,6 +2090,15 @@ void SVC_RemoteCommand (void)
|
|||
int i;
|
||||
char remaining[1024];
|
||||
|
||||
{
|
||||
bannedips_t *banip = SV_BannedAddress(&net_from);
|
||||
if (banip)
|
||||
{
|
||||
Con_Printf ("Rcon from banned ip %s\n", NET_AdrToString (net_from));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!Rcon_Validate ())
|
||||
{
|
||||
#ifdef SVRANKING
|
||||
|
@ -2362,136 +2370,8 @@ If 0, then only addresses matching the list will be allowed. This lets you easi
|
|||
==============================================================================
|
||||
*/
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned mask;
|
||||
unsigned compare;
|
||||
} ipfilter_t;
|
||||
|
||||
#define MAX_IPFILTERS 1024
|
||||
|
||||
ipfilter_t ipfilters[MAX_IPFILTERS];
|
||||
int numipfilters;
|
||||
|
||||
cvar_t filterban = SCVAR("filterban", "1");
|
||||
|
||||
/*
|
||||
=================
|
||||
StringToFilter
|
||||
=================
|
||||
*/
|
||||
qboolean StringToFilter (char *s, ipfilter_t *f)
|
||||
{
|
||||
char num[128];
|
||||
int i, j;
|
||||
qbyte b[4];
|
||||
qbyte m[4];
|
||||
|
||||
for (i=0 ; i<4 ; i++)
|
||||
{
|
||||
b[i] = 0;
|
||||
m[i] = 0;
|
||||
}
|
||||
|
||||
for (i=0 ; i<4 ; i++)
|
||||
{
|
||||
if (*s < '0' || *s > '9')
|
||||
{
|
||||
Con_Printf ("Bad filter address: %s\n", s);
|
||||
return false;
|
||||
}
|
||||
|
||||
j = 0;
|
||||
while (*s >= '0' && *s <= '9')
|
||||
{
|
||||
num[j++] = *s++;
|
||||
}
|
||||
num[j] = 0;
|
||||
b[i] = atoi(num);
|
||||
if (b[i] != 0)
|
||||
m[i] = 255;
|
||||
|
||||
if (!*s)
|
||||
break;
|
||||
s++;
|
||||
}
|
||||
|
||||
f->mask = *(unsigned *)m;
|
||||
f->compare = *(unsigned *)b;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
SV_AddIP_f
|
||||
=================
|
||||
*/
|
||||
void SV_AddIP_f (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0 ; i<numipfilters ; i++)
|
||||
if (ipfilters[i].compare == 0xffffffff)
|
||||
break; // free spot
|
||||
if (i == numipfilters)
|
||||
{
|
||||
if (numipfilters == MAX_IPFILTERS)
|
||||
{
|
||||
Con_Printf ("IP filter list is full\n");
|
||||
return;
|
||||
}
|
||||
numipfilters++;
|
||||
}
|
||||
|
||||
if (!StringToFilter (Cmd_Argv(1), &ipfilters[i]))
|
||||
ipfilters[i].compare = 0xffffffff;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
SV_RemoveIP_f
|
||||
=================
|
||||
*/
|
||||
void SV_RemoveIP_f (void)
|
||||
{
|
||||
ipfilter_t f;
|
||||
int i, j;
|
||||
|
||||
if (!StringToFilter (Cmd_Argv(1), &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--;
|
||||
Con_Printf ("Removed.\n");
|
||||
return;
|
||||
}
|
||||
Con_Printf ("Didn't find %s.\n", Cmd_Argv(1));
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
SV_ListIP_f
|
||||
=================
|
||||
*/
|
||||
void SV_ListIP_f (void)
|
||||
{
|
||||
int i;
|
||||
qbyte b[4];
|
||||
|
||||
Con_Printf ("Filter list:\n");
|
||||
for (i=0 ; i<numipfilters ; i++)
|
||||
{
|
||||
*(unsigned *)b = ipfilters[i].compare;
|
||||
Con_Printf ("%3i.%3i.%3i.%3i\n", b[0], b[1], b[2], b[3]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
SV_WriteIP_f
|
||||
|
@ -2499,6 +2379,8 @@ SV_WriteIP_f
|
|||
*/
|
||||
void SV_WriteIP_f (void)
|
||||
{
|
||||
// TODO: function needs to be rewritten to handle new banning and filtering logic
|
||||
/*
|
||||
vfsfile_t *f;
|
||||
char name[MAX_OSPATH];
|
||||
qbyte b[4];
|
||||
|
@ -2524,23 +2406,7 @@ void SV_WriteIP_f (void)
|
|||
}
|
||||
|
||||
VFS_CLOSE (f);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
SV_SendBan
|
||||
=================
|
||||
*/
|
||||
void SV_SendBan (void)
|
||||
{
|
||||
char data[128];
|
||||
|
||||
data[0] = data[1] = data[2] = data[3] = 0xff;
|
||||
data[4] = A2C_PRINT;
|
||||
data[5] = 0;
|
||||
strcat (data, "\nbanned.\n");
|
||||
|
||||
NET_SendPacket (NS_SERVER, strlen(data), data, net_from);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2548,20 +2414,34 @@ void SV_SendBan (void)
|
|||
SV_FilterPacket
|
||||
=================
|
||||
*/
|
||||
qboolean SV_FilterPacket (void)
|
||||
qboolean SV_FilterPacket (netadr_t *a)
|
||||
{
|
||||
int i;
|
||||
unsigned in;
|
||||
filteredips_t *banip;
|
||||
|
||||
in = *(unsigned *)net_from.address.ip;
|
||||
if (NET_IsLoopBackAddress(*a))
|
||||
return 0; // never filter loopback
|
||||
|
||||
for (i=0 ; i<numipfilters ; i++)
|
||||
if ( (in & ipfilters[i].mask) == ipfilters[i].compare)
|
||||
for (banip = svs.filteredips; banip; banip=banip->next)
|
||||
{
|
||||
if (NET_CompareAdrMasked(*a, banip->adr, banip->adrmask))
|
||||
return filterban.value;
|
||||
|
||||
}
|
||||
return !filterban.value;
|
||||
}
|
||||
|
||||
// SV_BannedAdress, run through ban address list and return corresponding bannedips_t
|
||||
// pointer, otherwise return NULL if not in the list
|
||||
bannedips_t *SV_BannedAddress (netadr_t *a)
|
||||
{
|
||||
bannedips_t *banip;
|
||||
for (banip = svs.bannedips; banip; banip=banip->next)
|
||||
{
|
||||
if (NET_CompareAdrMasked(*a, banip->adr, banip->adrmask))
|
||||
return banip;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//send a network packet to a new non-connected client.
|
||||
//this is to combat tunneling
|
||||
void SV_OpenRoute_f(void)
|
||||
|
@ -2598,11 +2478,8 @@ void SV_ReadPackets (void)
|
|||
good = false;
|
||||
while (SV_GetPacket ())
|
||||
{
|
||||
if (SV_FilterPacket ())
|
||||
{
|
||||
SV_SendBan (); // tell them we aren't listening...
|
||||
if (SV_FilterPacket (&net_from))
|
||||
continue;
|
||||
}
|
||||
|
||||
// check for connectionless packet (0xffffffff) first
|
||||
if (*(int *)net_message.data == -1)
|
||||
|
@ -3235,11 +3112,6 @@ void SV_InitLocal (void)
|
|||
|
||||
Cvar_Register (&sv_nailhack, cvargroup_servercontrol);
|
||||
|
||||
Cmd_AddCommand ("addip", SV_AddIP_f);
|
||||
Cmd_AddCommand ("removeip", SV_RemoveIP_f);
|
||||
Cmd_AddCommand ("listip", SV_ListIP_f);
|
||||
Cmd_AddCommand ("writeip", SV_WriteIP_f);
|
||||
|
||||
Cmd_AddCommand ("sv_impulse", SV_Impulse_f);
|
||||
|
||||
Cmd_AddCommand ("openroute", SV_OpenRoute_f);
|
||||
|
|
|
@ -2911,6 +2911,7 @@ void SVQ3_HandleClient(void)
|
|||
SVQ3_ParseClientMessage(&svs.clients[i]);
|
||||
}
|
||||
|
||||
bannedips_t *SV_BannedAddress (netadr_t *a);
|
||||
void SVQ3_DirectConnect(void) //Actually connect the client, use up a slot, and let the gamecode know of it.
|
||||
{
|
||||
char *reason;
|
||||
|
@ -2919,6 +2920,7 @@ void SVQ3_DirectConnect(void) //Actually connect the client, use up a slot, and
|
|||
int ret;
|
||||
int challenge;
|
||||
int qport;
|
||||
bannedips_t *banip;
|
||||
|
||||
if (net_message.cursize < 13)
|
||||
return;
|
||||
|
@ -2934,7 +2936,17 @@ void SVQ3_DirectConnect(void) //Actually connect the client, use up a slot, and
|
|||
if (!cl)
|
||||
cl = SVQ3_FindEmptyPlayerSlot();
|
||||
|
||||
if (!cl)
|
||||
banip = SV_BannedAddress(&net_from);
|
||||
|
||||
if (banip)
|
||||
{
|
||||
if (banip->reason[0])
|
||||
reason = banip->reason;
|
||||
else
|
||||
reason = "Banned.";
|
||||
userinfo = NULL;
|
||||
}
|
||||
else if (!cl)
|
||||
{
|
||||
reason = "Server is full.";
|
||||
userinfo = NULL;
|
||||
|
|
Loading…
Reference in a new issue