diff options
author | peter1138 <peter1138@openttd.org> | 2009-01-15 18:11:26 +0000 |
---|---|---|
committer | peter1138 <peter1138@openttd.org> | 2009-01-15 18:11:26 +0000 |
commit | a039ec0d21008668b79509d097b9a6f59ea64977 (patch) | |
tree | 00b19772b627a1b7b25426d63619b76801f6e19e /src/network | |
parent | 3e7c2bbacc8e44846f2f3f6a0b4b8c8183b25e1b (diff) | |
download | openttd-a039ec0d21008668b79509d097b9a6f59ea64977.tar.xz |
(svn r15094) -Feature: Add support for IP range bans using CIDR notation.
Diffstat (limited to 'src/network')
-rw-r--r-- | src/network/network.cpp | 25 |
1 files 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; } } |