Add sqlite function for ipv6 cidr testing
This commit is contained in:
@@ -40,6 +40,7 @@
|
||||
#include "network/race_event_manager.hpp"
|
||||
#include "network/server_config.hpp"
|
||||
#include "network/stk_host.hpp"
|
||||
#include "network/stk_ipv6.hpp"
|
||||
#include "network/stk_peer.hpp"
|
||||
#include "online/online_profile.hpp"
|
||||
#include "online/xml_request.hpp"
|
||||
@@ -59,6 +60,48 @@
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
|
||||
|
||||
#ifdef ENABLE_SQLITE3
|
||||
// ----------------------------------------------------------------------------
|
||||
void insideIPv6CIDRSQL(sqlite3_context* context, int argc,
|
||||
sqlite3_value** argv)
|
||||
{
|
||||
if (argc != 2)
|
||||
{
|
||||
sqlite3_result_int(context, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
char* ipv6_cidr = (char*)sqlite3_value_text(argv[0]);
|
||||
char* ipv6_in = (char*)sqlite3_value_text(argv[1]);
|
||||
if (ipv6_cidr == NULL || ipv6_in == NULL)
|
||||
{
|
||||
sqlite3_result_int(context, 0);
|
||||
return;
|
||||
}
|
||||
sqlite3_result_int(context, insideIPv6CIDR(ipv6_cidr, ipv6_in));
|
||||
} // insideIPv6CIDRSQL
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/*
|
||||
Copy below code so it can be use as loadable extension to be used in sqlite3
|
||||
command interface (together with andIPv6 and insideIPv6CIDR from stk_ipv6)
|
||||
|
||||
#include "sqlite3ext.h"
|
||||
SQLITE_EXTENSION_INIT1
|
||||
// ----------------------------------------------------------------------------
|
||||
sqlite3_extension_init(sqlite3* db, char** pzErrMsg,
|
||||
const sqlite3_api_routines* pApi)
|
||||
{
|
||||
SQLITE_EXTENSION_INIT2(pApi)
|
||||
sqlite3_create_function(db, "insideIPv6CIDR", 2, SQLITE_UTF8, NULL,
|
||||
insideIPv6CIDRSQL, NULL, NULL);
|
||||
return 0;
|
||||
} // sqlite3_extension_init
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
/** This is the central game setup protocol running in the server. It is
|
||||
* mostly a finite state machine. Note that all nodes in ellipses and light
|
||||
* grey background are actual states; nodes in boxes and white background
|
||||
@@ -202,7 +245,8 @@ void ServerLobby::initDatabase()
|
||||
// Return zero to let caller return SQLITE_BUSY immediately
|
||||
return 0;
|
||||
}, NULL);
|
||||
|
||||
sqlite3_create_function(m_db, "insideIPv6CIDR", 2, SQLITE_UTF8, NULL,
|
||||
&insideIPv6CIDRSQL, NULL, NULL);
|
||||
checkTableExists(ServerConfig::m_ip_ban_table, m_ip_ban_table_exists);
|
||||
checkTableExists(ServerConfig::m_online_id_ban_table,
|
||||
m_online_id_ban_table_exists);
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include <string.h>
|
||||
#ifdef WIN32
|
||||
#ifdef __GNUC__
|
||||
# include <ws2tcpip.h> // Mingw / gcc on windows
|
||||
@@ -26,6 +27,7 @@
|
||||
extern "C"
|
||||
{
|
||||
WINSOCK_API_LINKAGE PCSTR WSAAPI inet_ntop(INT Family, PVOID pAddr, PSTR pStringBuf, size_t StringBufSize);
|
||||
WINSOCK_API_LINKAGE INT WSAAPI inet_pton(INT Family, PCSTR pszAddrString, PVOID pAddrBuf);
|
||||
}
|
||||
|
||||
#else
|
||||
@@ -126,7 +128,53 @@ extern "C" int getaddrinfo_compat(const char* hostname,
|
||||
#else
|
||||
return getaddrinfo(hostname, servname, hints, res);
|
||||
#endif
|
||||
}
|
||||
} // getaddrinfo_compat
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void andIPv6(struct in6_addr* ipv6, const struct in6_addr* mask)
|
||||
{
|
||||
for (unsigned i = 0; i < sizeof(struct in6_addr); i++)
|
||||
ipv6->s6_addr[i] &= mask->s6_addr[i];
|
||||
} // andIPv6
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
extern "C" int insideIPv6CIDR(const char* ipv6_cidr, const char* ipv6_in)
|
||||
{
|
||||
const char* mask_location = strchr(ipv6_cidr, '/');
|
||||
if (mask_location == NULL)
|
||||
return 0;
|
||||
struct in6_addr v6_in;
|
||||
if (inet_pton(AF_INET6, ipv6_in, &v6_in) != 1)
|
||||
return 0;
|
||||
|
||||
char ipv6[INET6_ADDRSTRLEN] = {};
|
||||
memcpy(ipv6, ipv6_cidr, mask_location - ipv6_cidr);
|
||||
struct in6_addr cidr;
|
||||
if (inet_pton(AF_INET6, ipv6, &cidr) != 1)
|
||||
return 0;
|
||||
|
||||
int mask_length = atoi(mask_location + 1);
|
||||
if (mask_length > 128 || mask_length <= 0)
|
||||
return 0;
|
||||
|
||||
struct in6_addr mask = {};
|
||||
for (int i = mask_length, j = 0; i > 0; i -= 8, j++)
|
||||
{
|
||||
if (i >= 8)
|
||||
mask.s6_addr[j] = 0xff;
|
||||
else
|
||||
mask.s6_addr[j] = (unsigned long)(0xffU << (8 - i));
|
||||
}
|
||||
|
||||
andIPv6(&cidr, &mask);
|
||||
andIPv6(&v6_in, &mask);
|
||||
for (unsigned i = 0; i < sizeof(struct in6_addr); i++)
|
||||
{
|
||||
if (cidr.s6_addr[i] != v6_in.s6_addr[i])
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
} // andIPv6
|
||||
|
||||
#ifndef ENABLE_IPV6
|
||||
#include "network/stk_ipv6.hpp"
|
||||
|
||||
@@ -29,6 +29,7 @@ void getMappedFromIPV6(const struct sockaddr_in6* in6, ENetAddress* ea);
|
||||
void addMappedAddress(const ENetAddress* ea, const struct sockaddr_in6* in6);
|
||||
int getaddrinfo_compat(const char* hostname, const char* servname,
|
||||
const struct addrinfo* hints, struct addrinfo** res);
|
||||
int insideIPv6CIDR(const char* ipv6_cidr, const char* ipv6_in);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user