udp4th123.zip/udp_server.cpp
#include <winsock2.h>
#include <windows.h>
#include <vector>
#include <stdio.h>
class IPacketFilter {
protected:
std::vector<bool (*)(struct sockaddr_in, char *)> filters;
virtual bool CheckFilter(char *buffer) = 0;
public:
bool recv(char *buffer, int size) {
int _readSize;
return this->recv(buffer, size, &_readSize);
}
bool recv(char *buffer, int size, int *readSize) {
int _errorCode;
return this->recv(buffer, size, readSize, &_errorCode);
}
bool recv(char *buffer, int size, int *readSize, int *errorCode) {
while(true){
if(!receive(buffer, size, readSize, errorCode)){
return false;
}
if(*readSize == 0){
return true;
}
if(CheckFilter(buffer)){
return true;
}
}
}
virtual bool receive(char *buffer, int size, int *readSize, int *errorCode) = 0;
virtual void AddFilter(bool (*filter)(struct sockaddr_in, char *)) {
filters.push_back(filter);
}
};
class PacketFilter : public IPacketFilter {
protected:
SOCKET sock;
struct sockaddr_in saddr;
bool CheckFilter(char *buffer) {
std::vector<bool (*)(struct sockaddr_in, char *)>::iterator p = filters.begin();
while(p != filters.end()){
if(!(*p)(saddr, buffer)) {
return false;
}
++p;
}
return true;
}
public:
PacketFilter(u_long addr){
SetAddr(addr);
}
PacketFilter(const PacketFilter &obj) {
SetAddr(obj.saddr.sin_addr.s_addr);
}
void SetAddr(u_long addr){
DWORD flag = 1;
sock = socket(AF_INET,SOCK_RAW,IPPROTO_IP);
if(sock == INVALID_SOCKET){
printf("ソケットの取得に失敗しました");
}
memset(&saddr,0,sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = addr;
saddr.sin_port = htons(0);
if(bind(sock,(struct sockaddr *)&saddr,sizeof(struct sockaddr)) == SOCKET_ERROR){
printf("bind error\n");
}
if(0!=ioctlsocket(sock,0x98000001,&flag)){
printf("ioctlsocket error(0x98000001)\n");
}
if(0!=ioctlsocket(sock, FIONBIO, &flag)) {
printf("ioctlsocket error(FIONBIO)\n");
}
}
~PacketFilter() {
closesocket(sock);
}
bool receive(char *buffer, int size, int *readSize, int *errorCode) {
int recvRet;
int ret;
WSASetLastError(0);
recvRet = ::recv(sock, buffer, size, 0);
if(recvRet > 0){
ret = true;
*readSize = recvRet;
*errorCode = 0;
} else {
*readSize = 0;
*errorCode = WSAGetLastError();
if(*errorCode == WSAEWOULDBLOCK || *errorCode == 0){
*errorCode = 0;
ret = true;
} else {
ret = false;
}
}
return ret;
}
};
class FilterList : public IPacketFilter {
protected:
std::vector<PacketFilter> list;
bool CheckFilter(char *buffer) {
return true;
}
public:
void add(PacketFilter &filter) {
list.push_back(filter);
}
bool receive(char *buffer, int size, int *readSize, int *errorCode) {
std::vector<PacketFilter>::iterator p = list.begin();
while(p != list.end()){
const bool ret = p->recv(buffer, size, readSize, errorCode);
if(!ret) {
return false;
} else if(readSize > 0){
return true;
}
++p;
}
return true;
}
virtual void AddFilter(bool (*filter)(struct sockaddr_in, char *)) {
std::vector<PacketFilter>::iterator p = list.begin();
while(p != list.end()){
p->AddFilter(filter);
++p;
}
}
};
class NetworkAdapter {
private:
union {
u_long addr;
unsigned char addr_c[4];
};
char addr_s[17];
public:
NetworkAdapter(u_long _addr) {
addr = _addr;
sprintf(addr_s,"%d.%d.%d.%d",addr_c[0],addr_c[1],addr_c[2],addr_c[3]);
}
u_long GetAddr() {
return addr;
}
char *ToString() {
return addr_s;
}
PacketFilter CreatePacketFilter(){
PacketFilter pf(addr);
return pf;
}
};
class NetworkAdapters {
private:
std::vector<NetworkAdapter> Adapter;
public:
NetworkAdapters() {
SOCKET sock;
char buffer[1024];
SOCKET_ADDRESS_LIST *addressList = (SOCKET_ADDRESS_LIST *)buffer;
DWORD d;
if (INVALID_SOCKET == (sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP))) {
printf("INVALID_SOCKET\n");
exit(0);
}
if (WSAIoctl(sock, SIO_ADDRESS_LIST_QUERY, NULL, 0, buffer, sizeof(buffer), &d, NULL, NULL) != 0) {
printf("WSAIoctl error\n");
exit(0);
}
int i = 0;
while(i < addressList->iAddressCount) {
NetworkAdapter item(((SOCKADDR_IN*)addressList->Address[i].lpSockaddr)->sin_addr.s_addr);
Adapter.push_back(item);
i++;
}
}
FilterList CreatePacketFilter(){
FilterList pf;
std::vector<NetworkAdapter>::iterator p = Adapter.begin();
while(p != Adapter.end()){
pf.add(p->CreatePacketFilter());
++p;
}
return pf;
}
};
bool IsUDP(char *buffer) {
if((buffer[0]&0xF0) != 0x40){
return false;
}
if(((unsigned char *)buffer)[9] != 17) {
return false;
}
return true;
}
bool IsTCP(char *buffer) {
if((buffer[0]&0xF0) != 0x40){
return false;
}
if(((unsigned char *)buffer)[9] != 6) {
return false;
}
return true;
}
bool RecvAddressEqual(u_long addr, char *buffer) {
if(addr != *(u_long *)&buffer[16]) {
return false;
}
return true;
}
bool SendAddressEqual(u_long addr, char *buffer) {
if(addr != *(u_long *)&buffer[12]) {
return false;
}
return true;
}
bool RecvPortEqual(unsigned short port, char *buffer) {
int addr;
addr = (((unsigned char *)buffer)[0] & 0x0F) * 4;
addr = addr + 2;
if(port != ((*(unsigned char *)&buffer[addr]) << 8) + *(unsigned char *)&buffer[addr+1]) {
return false;
}
return true;
}
bool SendPortEqual(unsigned short port, char *buffer) {
int addr;
addr = (((unsigned char *)buffer)[0] & 0x0F) * 4;
if(port != ((*(unsigned char *)&buffer[addr]) << 8) + *(unsigned char *)&buffer[addr+1]) {
return false;
}
return true;
}
bool MyFilter(struct sockaddr_in addr, char *buffer) {
return IsUDP(buffer) && RecvAddressEqual(addr.sin_addr.s_addr, buffer) && RecvPortEqual(10800, buffer);
}
char *GetBody(char *buffer) {
int addr;
addr = (((unsigned char *)buffer)[0] & 0x0F) * 4;
if(IsUDP(buffer)){
addr += 8;
} else if(IsTCP(buffer)){
addr += ((((unsigned char *)buffer)[addr + 12] & 0xF0) >> 4) * 4;
}
return &buffer[addr];
}
class ToolUseChecker {
protected:
FilterList pf;
public:
ToolUseChecker() {
NetworkAdapters na;
pf = na.CreatePacketFilter();
pf.AddFilter(MyFilter);
}
bool Check() {
char checkBuf[] = {
0x01,
0x02, 0x00, 0x2A, 0x31, 0x56, 0x6F, 0x69, 0x63, 0x65, 0x4D, 0x61, 0x6E, 0x61, 0x67, 0x65, 0x72,
0x02, 0x00, 0x2A, 0x31, 0x56, 0x6F, 0x69, 0x63, 0x65, 0x4D, 0x61, 0x6E, 0x61, 0x67, 0x65, 0x72,
0x00, 0x00, 0x00, 0x00
};
char buffer[4096];
int RecvSize;
while(TRUE){
if(pf.recv(buffer, sizeof(buffer), &RecvSize)) {
if(RecvSize == 0){
return false;
}
if(!IsUDP(buffer)){
continue;
}
if(0 != memcmp(GetBody(buffer),checkBuf,sizeof(checkBuf))){
continue;
}
break;
}
return false;
}
return true;
}
};
int main(){
WSADATA wsad;
if(WSAStartup(MAKEWORD(2,1),&wsad)){
printf("初期化に失敗しました");
return -1;
}
if(wsad.wVersion != MAKEWORD(2,1)){
printf("未対応のバージョンです");
return -1;
}
ToolUseChecker checker;
while(true) {
if(checker.Check()) {
puts("success\n");
}
Sleep(1000);
}
return 0;
}