Initial commit: server + serverfiles

This commit is contained in:
Game
2026-08-17 17:31:44 +00:00
commit ff1237686b
17389 changed files with 868929 additions and 0 deletions
+374
View File
@@ -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;
};