forked from metin2/server
373 lines
5.6 KiB
C++
373 lines
5.6 KiB
C++
//#define __MAIN__
|
|
#ifdef __MAIN__
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
#include <netinet/in.h>
|
|
#include <arpa/inet.h>
|
|
#include <vector>
|
|
#include <algorithm>
|
|
|
|
typedef unsigned char BYTE;
|
|
typedef unsigned long DWORD;
|
|
|
|
#else
|
|
|
|
#include "stdafx.h"
|
|
#include "ip_ban.h"
|
|
|
|
#endif
|
|
|
|
class IP
|
|
{
|
|
public:
|
|
IP()
|
|
: dwStart(0), dwEnd(0), dwMask(0)
|
|
{}
|
|
|
|
IP(const IP & r)
|
|
{
|
|
dwStart = r.dwStart;
|
|
dwEnd = r.dwEnd;
|
|
dwMask = r.dwMask;
|
|
}
|
|
|
|
IP(const char * c_pszStart, const char * c_pszEnd = NULL)
|
|
{
|
|
BYTE start[4];
|
|
BYTE end[4];
|
|
BYTE mask[4];
|
|
|
|
Read(c_pszStart, start);
|
|
|
|
if (c_pszEnd && *c_pszEnd)
|
|
Read(c_pszEnd, end);
|
|
else
|
|
memcpy(end, start, sizeof(BYTE) * 4);
|
|
|
|
mask[0] = 255 - (start[0] ^ end[0]);
|
|
mask[1] = 255 - (start[1] ^ end[1]);
|
|
mask[2] = 255 - (start[2] ^ end[2]);
|
|
mask[3] = 255 - (start[3] ^ end[3]);
|
|
|
|
dwStart = (start[3] << 24) | (start[2] << 16) | (start[1] << 8) | start[0];
|
|
dwEnd = (end[3] << 24) | (end[2] << 16) | (end[1] << 8) | end[0];
|
|
dwMask = (mask[3] << 24) | (mask[2] << 16) | (mask[1] << 8) | mask[0];
|
|
|
|
Print();
|
|
}
|
|
|
|
IP(struct in_addr in)
|
|
{
|
|
dwStart = in.s_addr;
|
|
dwEnd = dwStart;
|
|
dwMask = 4294967295UL;
|
|
}
|
|
|
|
bool IsEqual(const IP & r) const
|
|
{
|
|
return (dwStart == r.dwStart && dwEnd == r.dwEnd && dwMask == r.dwMask);
|
|
}
|
|
|
|
bool IsChildOf(IP & r)
|
|
{
|
|
if ((r.dwStart & r.dwMask) != (dwStart & r.dwMask))
|
|
return false;
|
|
|
|
DWORD m = r.dwMask | dwMask;
|
|
|
|
return (dwStart & ~m) == (dwStart & ~dwMask) && (dwEnd & ~m) == (dwEnd & ~dwMask);
|
|
}
|
|
|
|
int hash()
|
|
{
|
|
return (dwStart & 0x000000FF);
|
|
}
|
|
|
|
void Print()
|
|
{
|
|
struct in_addr in_ip, in_mask, in_end;
|
|
|
|
in_ip.s_addr = dwStart;
|
|
in_mask.s_addr = dwMask;
|
|
in_end.s_addr = dwEnd;
|
|
|
|
fprintf(stderr, "\t%s", inet_ntoa(in_ip));
|
|
fprintf(stderr, "\t%s", inet_ntoa(in_end));
|
|
fprintf(stderr, "\t%s\tfirst %d\n", inet_ntoa(in_mask), hash());
|
|
}
|
|
|
|
protected:
|
|
bool Read(const char * s, BYTE * dest)
|
|
{
|
|
BYTE bClass = 0;
|
|
const char * p = s;
|
|
|
|
while (bClass < 3)
|
|
{
|
|
char szNum[4];
|
|
char * pDot = const_cast<char*>(strchr(p, '.'));
|
|
|
|
if (!pDot)
|
|
break;
|
|
|
|
strncpy(szNum, p, sizeof(szNum));
|
|
|
|
str_to_number(dest[bClass++], szNum);
|
|
p = pDot + 1;
|
|
}
|
|
|
|
if (bClass != 3)
|
|
{
|
|
fprintf(stderr, "error reading start %s\n", s);
|
|
return false;
|
|
}
|
|
|
|
str_to_number(dest[bClass], p);
|
|
return true;
|
|
}
|
|
|
|
DWORD dwStart;
|
|
DWORD dwEnd;
|
|
DWORD dwMask;
|
|
};
|
|
|
|
std::map<int, std::vector<IP> > mapBanIP;
|
|
|
|
bool LoadBanIP(const char * filename)
|
|
{
|
|
FILE * fp = fopen(filename, "r");
|
|
|
|
if (!fp)
|
|
return false;
|
|
|
|
char buf[256];
|
|
char start[256];
|
|
char end[256];
|
|
|
|
fprintf(stderr, "LOADING BANNED IP LIST\n");
|
|
|
|
while (fgets(buf, 256, fp))
|
|
{
|
|
*strchr(buf, '\n') = '\0';
|
|
char * p = strchr(buf, '\t');
|
|
|
|
if (!p)
|
|
{
|
|
strncpy(start, buf, sizeof(start));
|
|
*end = '\0';
|
|
}
|
|
else
|
|
{
|
|
char * p2 = strchr(p + 1, '\t');
|
|
|
|
if (p2)
|
|
*p2 = '\0';
|
|
|
|
strncpy(end, p + 1, sizeof(end));
|
|
|
|
*p = '\0';
|
|
strncpy(start, buf, sizeof(start));
|
|
}
|
|
|
|
IP ip(start, end);
|
|
|
|
itertype(mapBanIP) it = mapBanIP.find(ip.hash());
|
|
|
|
if (it == mapBanIP.end())
|
|
{
|
|
std::vector<IP> v;
|
|
v.push_back(ip);
|
|
mapBanIP.insert(std::map<DWORD, std::vector<IP> >::value_type(ip.hash(), v));
|
|
}
|
|
else
|
|
it->second.push_back(ip);
|
|
}
|
|
|
|
fclose(fp);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool IsBanIP(struct in_addr in)
|
|
{
|
|
IP ip(in);
|
|
|
|
itertype(mapBanIP) it = mapBanIP.find(ip.hash());
|
|
|
|
if (it == mapBanIP.end())
|
|
return false;
|
|
|
|
itertype(it->second) it2 = it->second.begin();
|
|
|
|
while (it2 != it->second.end())
|
|
if (ip.IsChildOf(*(it2++)))
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
#ifdef __MAIN__
|
|
void UniqueIP(std::vector<IP> & v)
|
|
{
|
|
using namespace std;
|
|
|
|
bool found;
|
|
vector<IP>::iterator it1;
|
|
|
|
do
|
|
{
|
|
vector<IP> o;
|
|
it1 = v.begin();
|
|
|
|
while (it1 != v.end())
|
|
{
|
|
IP & ip1 = *(it1++);
|
|
|
|
found = false;
|
|
|
|
if (it1 != v.end())
|
|
{
|
|
vector<IP>::iterator it2 = it1;
|
|
|
|
while (it2 != v.end())
|
|
{
|
|
IP & ip2 = *(it2++);
|
|
|
|
if (ip1.IsEqual(ip2))
|
|
{
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!found)
|
|
o.push_back(ip1);
|
|
}
|
|
|
|
if (o.size() == v.size())
|
|
break;
|
|
|
|
v.clear();
|
|
it1 = o.begin();
|
|
|
|
while (it1 != o.end())
|
|
v.push_back(*(it1++));
|
|
}
|
|
while (1);
|
|
}
|
|
|
|
void FilterIP(std::vector<IP> & v)
|
|
{
|
|
using namespace std;
|
|
|
|
bool found;
|
|
vector<IP>::iterator it1;
|
|
|
|
do
|
|
{
|
|
vector<IP> o;
|
|
it1 = v.begin();
|
|
|
|
while (it1 != v.end())
|
|
{
|
|
IP & ip1 = *(it1++);
|
|
|
|
found = false;
|
|
|
|
vector<IP>::iterator it2 = v.begin();
|
|
|
|
while (it2 != v.end())
|
|
{
|
|
IP & ip2 = *(it2++);
|
|
|
|
if (ip1.IsEqual(ip2))
|
|
continue;
|
|
|
|
if (ip1.IsChildOf(ip2))
|
|
{
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!found)
|
|
o.push_back(ip1);
|
|
}
|
|
|
|
if (o.size() == v.size())
|
|
break;
|
|
|
|
v.clear();
|
|
it1 = o.begin();
|
|
|
|
while (it1 != o.end())
|
|
v.push_back(*(it1++));
|
|
}
|
|
while (1);
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
using namespace std;
|
|
|
|
if (argc != 2)
|
|
{
|
|
printf("Syntax: %s <filename>\n", *argv);
|
|
return 1;
|
|
}
|
|
|
|
argc--, argv++;
|
|
|
|
FILE * fp = fopen(*argv, "r");
|
|
|
|
if (!fp)
|
|
return 0;
|
|
|
|
vector<IP> v;
|
|
char buf[256];
|
|
char start[32];
|
|
char end[32];
|
|
|
|
while (fgets(buf, 256, fp))
|
|
{
|
|
*strchr(buf, '\n') = '\0';
|
|
char * p = strchr(buf, '\t');
|
|
|
|
if (!p)
|
|
{
|
|
strncpy(start, buf, sizeof(start));
|
|
*end = '\0';
|
|
}
|
|
else
|
|
{
|
|
strncpy(end, p + 1, sizeof(end));
|
|
*p = '\0';
|
|
strncpy(start, buf, sizeof(start));
|
|
}
|
|
|
|
v.push_back(IP(start, end));
|
|
}
|
|
|
|
fclose(fp);
|
|
|
|
printf("size %d\n", v.size());
|
|
UniqueIP(v);
|
|
printf("result1 %d\n", v.size());
|
|
FilterIP(v);
|
|
printf("result2 %d\n", v.size());
|
|
|
|
vector<IP>::iterator it = v.begin();
|
|
|
|
while (it != v.end())
|
|
(*(it++)).Print();
|
|
|
|
return 1;
|
|
}
|
|
|
|
#endif
|