Initial commit: server + serverfiles
This commit is contained in:
Executable
+374
@@ -0,0 +1,374 @@
|
||||
#pragma once
|
||||
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <ctype.h>
|
||||
#include <map>
|
||||
#include <assert.h>
|
||||
#include <iostream>
|
||||
#include <stdio.h>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
// #define _snprintf snprintf
|
||||
#ifdef _WIN32
|
||||
#include <WinSock2.h>
|
||||
#define FORCEINLINE __forceinline
|
||||
#pragma comment(lib, "Ws2_32.lib")
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#define FORCEINLINE inline
|
||||
#define strcpy_s(__dst, __len, __src) strncpy(__dst, __src, __len)
|
||||
#define _stricmp(__dst, __src) strcasecmp(__dst, __src)
|
||||
#define strncpy_s(__dst, __dstlen, __src, __srclen) strncpy(__dst, __src, __srclen)
|
||||
#endif
|
||||
|
||||
class SIM
|
||||
{
|
||||
public:
|
||||
SIM() {};
|
||||
|
||||
enum
|
||||
{
|
||||
SIM_IP_MAC_TYPE,
|
||||
SIM_IP_RANGE_TYPE,
|
||||
SIM_IP_TYPE,
|
||||
};
|
||||
|
||||
//
|
||||
// SIM 파일의 한 line을 파싱한다.
|
||||
//
|
||||
bool ParseLine(const char* line)
|
||||
{
|
||||
char buf[1024];
|
||||
strcpy_s(buf, sizeof(buf), line);
|
||||
|
||||
// \t를 찾아보고 있으면, [IP]\t[MAC]\n 규칙으로 파싱한다.
|
||||
char* tpos = strchr(buf, '\t');
|
||||
if (tpos)
|
||||
{
|
||||
*tpos = 0;
|
||||
|
||||
// ip와 mac
|
||||
unsigned int ip = htonl(inet_addr(buf));
|
||||
char* mac = tpos + 1;
|
||||
|
||||
if (false == checkmac(mac))
|
||||
{
|
||||
printf("invalid MAC address - mac(%s)\n", mac);
|
||||
return false;
|
||||
}
|
||||
|
||||
printf("IP-MAC type added - ip(%u) mac(%s)\n", ip, mac);
|
||||
|
||||
macips.insert(MAC_IP_map::value_type(mac, ip));
|
||||
return true;
|
||||
}
|
||||
|
||||
// ~를 찾아보고 있으면, [IP]~[IP]\n 규칙으로 파싱한다.
|
||||
char* tilt = strchr(buf, '~');
|
||||
if (tilt)
|
||||
{
|
||||
*tilt = 0;
|
||||
|
||||
// begin ip와 end ip
|
||||
char* bip = buf;
|
||||
char* eip = tilt + 1;
|
||||
|
||||
IPRANGE ipr;
|
||||
ipr.fromip = htonl(inet_addr(bip));
|
||||
ipr.toip = htonl(inet_addr(eip));
|
||||
|
||||
printf("IP RANGE type added - begin[%u] end[%u]\n", ipr.fromip, ipr.toip);
|
||||
|
||||
ipranges.push_back(ipr);
|
||||
return true;
|
||||
}
|
||||
|
||||
// \t나 ~가 없으면, [IP]\n 규칙으로 파싱한다.
|
||||
unsigned int ip = htonl(inet_addr(buf));
|
||||
|
||||
printf("single IP type added - ip(%u)\n", ip);
|
||||
|
||||
ips.push_back(ip);
|
||||
return true;
|
||||
}
|
||||
|
||||
// ParseLine()으로 얻은 데이터를 binary로 변환
|
||||
void MakeBinary(std::vector<unsigned char>& s)
|
||||
{
|
||||
//
|
||||
// buf에 binary 형태로 기록
|
||||
//
|
||||
for (MAC_IP_map::iterator i = macips.begin(); i != macips.end(); ++i)
|
||||
{
|
||||
const std::string& mac = i->first;
|
||||
unsigned int ip = i->second;
|
||||
|
||||
unsigned char macbuf[6];
|
||||
mac2bin(mac, macbuf);
|
||||
|
||||
unsigned char type = SIM_IP_MAC_TYPE;
|
||||
|
||||
// [type(1)][ip(4)][mac(6)] 총 11바이트
|
||||
s.push_back(type);
|
||||
s.insert(s.end(), (unsigned char *)&ip, (unsigned char *)&ip + sizeof(ip));
|
||||
s.insert(s.end(), macbuf, macbuf + sizeof(macbuf));
|
||||
}
|
||||
|
||||
for (IPRanges::iterator i = ipranges.begin(); i != ipranges.end(); ++i)
|
||||
{
|
||||
unsigned int bip = (*i).fromip;
|
||||
unsigned int eip = (*i).toip;
|
||||
|
||||
unsigned char type = SIM_IP_RANGE_TYPE;
|
||||
|
||||
// [type(1)][ip(4)][ip(4)]
|
||||
s.push_back(type);
|
||||
s.insert(s.end(), (unsigned char *)&bip, (unsigned char *)&bip + sizeof(bip));
|
||||
s.insert(s.end(), (unsigned char *)&eip, (unsigned char *)&eip + sizeof(eip));
|
||||
}
|
||||
|
||||
for (IPs::iterator i = ips.begin(); i != ips.end(); ++i)
|
||||
{
|
||||
unsigned int ip = *i;
|
||||
|
||||
unsigned char type = SIM_IP_TYPE;
|
||||
|
||||
// [type(1)][ip(4)]
|
||||
s.push_back(type);
|
||||
s.insert(s.end(), (unsigned char *)&ip, (unsigned char *)&ip + sizeof(ip));
|
||||
}
|
||||
}
|
||||
|
||||
// sim binary를 parsing해서 데이터 채움
|
||||
bool ParseBinary(const char* buf, int buflen)
|
||||
{
|
||||
unsigned char* iter = (unsigned char *)buf;
|
||||
while (iter != (unsigned char *)buf + buflen)
|
||||
{
|
||||
unsigned char type = *iter++;
|
||||
switch (type)
|
||||
{
|
||||
case SIM_IP_MAC_TYPE:
|
||||
// [type(1)][ip(4)][mac(6)]
|
||||
{
|
||||
unsigned int ip = 0;
|
||||
memcpy(&ip, iter, sizeof(ip));
|
||||
iter += sizeof(ip);
|
||||
|
||||
char mac[18]; // AA-BB-CC-DD-EE-FF
|
||||
bin2mac(iter, mac);
|
||||
iter += 6;
|
||||
|
||||
#ifdef _DEBUG
|
||||
printf("IP-MAC type added - ip(%u) mac(%s)\n", ip, mac);
|
||||
#endif
|
||||
|
||||
macips.insert(MAC_IP_map::value_type(mac, ip));
|
||||
break;
|
||||
}
|
||||
case SIM_IP_RANGE_TYPE:
|
||||
// [type(1)][ip(4)][ip(4)]
|
||||
{
|
||||
unsigned int bip = 0;
|
||||
memcpy(&bip, iter, sizeof(bip));
|
||||
iter += sizeof(bip);
|
||||
|
||||
unsigned int eip = 0;
|
||||
memcpy(&eip, iter, sizeof(eip));
|
||||
iter += sizeof(eip);
|
||||
|
||||
IPRANGE ipr;
|
||||
ipr.fromip = bip;
|
||||
ipr.toip = eip;
|
||||
|
||||
#ifdef _DEBUG
|
||||
printf("IP RANGE type added - begin[%u] end[%u]\n", ipr.fromip, ipr.toip);
|
||||
#endif
|
||||
|
||||
ipranges.push_back(ipr);
|
||||
break;
|
||||
}
|
||||
case SIM_IP_TYPE:
|
||||
// [type(1)][ip(4)]
|
||||
{
|
||||
unsigned int ip = 0;
|
||||
memcpy(&ip, iter, sizeof(ip));
|
||||
iter += sizeof(ip);
|
||||
|
||||
#ifdef _DEBUG
|
||||
printf("single IP type added - ip(%u)\n", ip);
|
||||
#endif
|
||||
|
||||
ips.push_back(ip);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
#ifdef _DEBUG
|
||||
printf("parseBinary: invalid type (%u)\n", type);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
FORCEINLINE bool CheckIpAndMac(const char* ip, const char* mac)
|
||||
{
|
||||
assert(ip);
|
||||
assert(mac);
|
||||
|
||||
unsigned int uip = htonl(inet_addr(ip));
|
||||
|
||||
// ip & mac 체크
|
||||
for (MAC_IP_map::iterator i = macips.begin(); i != macips.end(); ++i)
|
||||
{
|
||||
const char* allowmac = i->first.c_str();
|
||||
unsigned int allowip = i->second;
|
||||
|
||||
// ip는 같은데 mac이 다른 경우
|
||||
if (allowip == uip && _stricmp(allowmac, mac))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// mac은 같은데 ip가 다른 경우
|
||||
if (_stricmp(allowmac, mac) == 0 && allowip != uip)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// ip와 mac이 모두 같은 경우
|
||||
if (allowip == uip && _stricmp(allowmac, mac) == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// ip와 mac이 모두 다른 경우는 pass
|
||||
}
|
||||
|
||||
// 범위 체크
|
||||
for (size_t i = 0; i < ipranges.size(); i++)
|
||||
{
|
||||
if (ipranges[i].fromip <= uip && uip <= ipranges[i].toip)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// 싱글 ip 체크
|
||||
for (size_t i = 0; i < ips.size(); i++)
|
||||
{
|
||||
if (uip == ips[i])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
typedef std::map<std::string, unsigned int> MAC_IP_map; // MAC(string)을 키로 ip(uint)를 찾음
|
||||
typedef std::vector<unsigned int> IPs; // single ip(uint)
|
||||
struct IPRANGE
|
||||
{
|
||||
unsigned int fromip; // ip range (begin)
|
||||
unsigned int toip; // ip ragne (end)
|
||||
};
|
||||
typedef std::vector<IPRANGE> IPRanges;
|
||||
|
||||
private:
|
||||
bool checkmac(const char* mac)
|
||||
{
|
||||
size_t len = strlen(mac);
|
||||
if (len != 12 && len != 17)
|
||||
{
|
||||
// 길이 이상
|
||||
printf("checkmac - invalid length (%s)(%u)\n", mac, len);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < len; i++)
|
||||
{
|
||||
// 하이픈(-) 체크
|
||||
if (len == 17 && i % 3 == 2)
|
||||
{
|
||||
if (mac[i] == '-')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("checkmac - cannot find '-' (%s)\n", mac);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 문자 범위 검사
|
||||
if (mac[i] >= '0' && mac[i] <= '9') continue;
|
||||
if (mac[i] >= 'A' && mac[i] <= 'F') continue;
|
||||
if (mac[i] >= 'a' && mac[i] <= 'f') continue;
|
||||
|
||||
// 알수 없는 문자
|
||||
printf("checkmac - invalid character (%s)(%c)\n", mac, mac[i]);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mac2bin(const std::string& mac, unsigned char* outbuf)
|
||||
{
|
||||
assert(mac.size() == 12 || mac.size() == 17); // AABBCCDDEEFF 형태이거나 AA-BB-CC-DD-EE-FF 형태이거나
|
||||
|
||||
if (mac.size() == 12)
|
||||
{
|
||||
for (size_t i = 0, k = 0; i < mac.size(); i += 2, k++)
|
||||
{
|
||||
char buf[3] = {0, };
|
||||
strncpy_s(buf, sizeof(buf), &mac[i], 2);
|
||||
|
||||
unsigned char b = atoi(buf);
|
||||
outbuf[k] = b;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if (mac.size() == 17)
|
||||
{
|
||||
for (size_t i = 0, k = 0; i < mac.size(); i += 3, k++)
|
||||
{
|
||||
char buf[3] = {0, };
|
||||
strncpy_s(buf, sizeof(buf), &mac[i], 2);
|
||||
|
||||
char* endptr = buf + 2;
|
||||
unsigned char b = (unsigned char)strtol(buf, &endptr, 16);
|
||||
outbuf[k] = b;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void bin2mac(unsigned char* bin, char* outbuf)
|
||||
{
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
snprintf(outbuf + (i*3), 3, "%02X", bin[i]);
|
||||
|
||||
// 마지막엔 하이픈(-) 안 붙임
|
||||
if (i < 5)
|
||||
{
|
||||
strcat(outbuf, "-");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
MAC_IP_map macips; // mac-ip 조합을 먼저 검사한다. (우선순위 높음)
|
||||
IPRanges ipranges;
|
||||
IPs ips;
|
||||
};
|
||||
Reference in New Issue
Block a user