From 31a586dc6f5169ee0be89c66662948a5c555c497 Mon Sep 17 00:00:00 2001 From: peter1138 Date: Thu, 15 Jan 2009 18:11:26 +0000 Subject: (svn r15094) -Feature: Add support for IP range bans using CIDR notation. --- src/network/network.cpp | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/network/network.cpp b/src/network/network.cpp index ffda6a1f9..2379c46a2 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -511,7 +511,28 @@ static void NetworkAcceptClients() for (i = 0; i < lengthof(_network_ban_list); i++) { if (_network_ban_list[i] == NULL) continue; - if (sin.sin_addr.s_addr == inet_addr(_network_ban_list[i])) { + /* Check for CIDR separator */ + char *chr_cidr = strchr(_network_ban_list[i], '/'); + if (chr_cidr != NULL) { + int cidr = atoi(chr_cidr + 1); + + /* Invalid CIDR, treat as single host */ + if (cidr <= 0 || cidr > 32) cidr = 32; + + /* Remove and then replace the / so that inet_addr() works on the IP portion */ + *chr_cidr = '\0'; + uint32 ban_ip = inet_addr(_network_ban_list[i]); + *chr_cidr = '/'; + + /* Convert CIDR to mask in network format */ + uint32 mask = htonl(-(1 << (32 - cidr))); + if ((sin.sin_addr.s_addr & mask) == (ban_ip & mask)) banned = true; + } else { + /* No CIDR used, so just perform a simple IP test */ + if (sin.sin_addr.s_addr == inet_addr(_network_ban_list[i])) banned = true; + } + + if (banned) { Packet p(PACKET_SERVER_BANNED); p.PrepareToSend(); @@ -519,8 +540,6 @@ static void NetworkAcceptClients() send(s, (const char*)p.buffer, p.size, 0); closesocket(s); - - banned = true; break; } } -- cgit v1.2.3-54-g00ecf