static qboolean SV_IsBanned( netadr_t *from, qboolean isexception ) { int index; serverBan_t *curban; if ( !serverBansCount ) { return qfalse; } if ( !isexception ) { // If this is a query for a ban, first check whether the client is excepted if ( SV_IsBanned( from, qtrue ) ) return qfalse; } for ( index = 0; index < serverBansCount; index++ ) { curban = &serverBans[index]; if ( curban->isexception == isexception ) { if ( NET_CompareBaseAdrMask( curban->ip, *from, curban->subnet ) ) return qtrue; } } return qfalse; }
static bool SV_IsRconWhitelisted(netadr_t *from) { int index; serverRcon_t *curban; for(index = 0; index < rconWhitelistCount; index++) { curban = &rconWhitelist[index]; if(NET_CompareBaseAdrMask(curban->ip, *from, curban->subnet)) return true; } return false; }
/* =================== NET_CompareBaseAdr Compares without the port =================== */ qboolean NET_CompareBaseAdr( netadr_t a, netadr_t b ) { return NET_CompareBaseAdrMask( a, b, -1 ); }
static void SV_DelBanFromList(qboolean isexception) { int index, count = 0, todel, mask; netadr_t ip; char *banstring; if(Cmd_Argc() != 2) { Com_Printf ("Usage: %s (ip[/subnet] | num)\n", Cmd_Argv(0)); return; } banstring = Cmd_Argv(1); if(strchr(banstring, '.') || strchr(banstring, ':')) { serverBan_t *curban; if(SV_ParseCIDRNotation(&ip, &mask, banstring)) { Com_Printf("Error: Invalid address %s\n", banstring); return; } index = 0; while(index < serverBansCount) { curban = &serverBans[index]; if(curban->isexception == isexception && curban->subnet >= mask && NET_CompareBaseAdrMask(curban->ip, ip, mask)) { Com_Printf("Deleting %s %s/%d\n", isexception ? "exception" : "ban", NET_AdrToString(curban->ip), curban->subnet); SV_DelBanEntryFromList(index); } else index++; } } else { todel = atoi(Cmd_Argv(1)); if(todel < 1 || todel > serverBansCount) { Com_Printf("Error: Invalid ban number given\n"); return; } for(index = 0; index < serverBansCount; index++) { if(serverBans[index].isexception == isexception) { count++; if(count == todel) { Com_Printf("Deleting %s %s/%d\n", isexception ? "exception" : "ban", NET_AdrToString(serverBans[index].ip), serverBans[index].subnet); SV_DelBanEntryFromList(index); break; } } } } SV_WriteBans(); }
static void SV_AddBanToList(qboolean isexception) { char *banstring; char addy2[NET_ADDRSTRMAXLEN]; netadr_t ip; int index, argc, mask; serverBan_t *curban; argc = Cmd_Argc(); if(argc < 2 || argc > 3) { Com_Printf ("Usage: %s (ip[/subnet] | clientnum [subnet])\n", Cmd_Argv(0)); return; } if(serverBansCount > ARRAY_LEN(serverBans)) { Com_Printf ("Error: Maximum number of bans/exceptions exceeded.\n"); return; } banstring = Cmd_Argv(1); if(strchr(banstring, '.') || strchr(banstring, ':')) { // This is an ip address, not a client num. if(SV_ParseCIDRNotation(&ip, &mask, banstring)) { Com_Printf("Error: Invalid address %s\n", banstring); return; } } else { client_t *cl; // client num. if(!com_sv_running->integer) { Com_Printf("Server is not running.\n"); return; } cl = SV_GetPlayerByNum(); if(!cl) { Com_Printf("Error: Playernum %s does not exist.\n", Cmd_Argv(1)); return; } ip = cl->netchan.remoteAddress; if(argc == 3) { mask = atoi(Cmd_Argv(2)); if(ip.type == NA_IP) { if(mask < 1 || mask > 32) mask = 32; } else { if(mask < 1 || mask > 128) mask = 128; } } else mask = (ip.type == NA_IP6) ? 128 : 32; } if(ip.type != NA_IP && ip.type != NA_IP6) { Com_Printf("Error: Can ban players connected via the internet only.\n"); return; } // first check whether a conflicting ban exists that would supersede the new one. for(index = 0; index < serverBansCount; index++) { curban = &serverBans[index]; if(curban->subnet <= mask) { if((curban->isexception || !isexception) && NET_CompareBaseAdrMask(curban->ip, ip, curban->subnet)) { Q_strncpyz(addy2, NET_AdrToString(ip), sizeof(addy2)); Com_Printf("Error: %s %s/%d supersedes %s %s/%d\n", curban->isexception ? "Exception" : "Ban", NET_AdrToString(curban->ip), curban->subnet, isexception ? "exception" : "ban", addy2, mask); return; } } if(curban->subnet >= mask) { if(!curban->isexception && isexception && NET_CompareBaseAdrMask(curban->ip, ip, mask)) { Q_strncpyz(addy2, NET_AdrToString(curban->ip), sizeof(addy2)); Com_Printf("Error: %s %s/%d supersedes already existing %s %s/%d\n", isexception ? "Exception" : "Ban", NET_AdrToString(ip), mask, curban->isexception ? "exception" : "ban", addy2, curban->subnet); return; } } } // now delete bans that are superseded by the new one index = 0; while(index < serverBansCount) { curban = &serverBans[index]; if(curban->subnet > mask && (!curban->isexception || isexception) && NET_CompareBaseAdrMask(curban->ip, ip, mask)) SV_DelBanEntryFromList(index); else index++; } serverBans[serverBansCount].ip = ip; serverBans[serverBansCount].subnet = mask; serverBans[serverBansCount].isexception = isexception; serverBansCount++; SV_WriteBans(); Com_Printf("Added %s: %s/%d\n", isexception ? "ban exception" : "ban", NET_AdrToString(ip), mask); }