From 01946f5d481101ebdb342218b924a348392d0cd4 Mon Sep 17 00:00:00 2001 From: malloc Date: Wed, 6 Feb 2019 10:44:58 -0600 Subject: [PATCH] COOL FUCKING GAME --- resources/NULL | 1 + src/main.c | 8 ++ src/sock/tcp.h | 58 ++++++++++ src/sock/tcp_bsd.c | 6 + src/sock/tcp_win.c | 4 + src/util/ipaddr.c | 248 ++++++++++++++++++++++++++++++++++++++++ src/util/ipaddr.h | 29 +++++ src/util/string.c | 25 ++++ src/util/string.h | 9 ++ src/util/thread.h | 37 ++++++ src/util/thread_posix.c | 61 ++++++++++ src/util/thread_win.c | 44 +++++++ 12 files changed, 530 insertions(+) create mode 100644 resources/NULL create mode 100644 src/main.c create mode 100644 src/sock/tcp.h create mode 100644 src/sock/tcp_bsd.c create mode 100644 src/sock/tcp_win.c create mode 100644 src/util/ipaddr.c create mode 100644 src/util/ipaddr.h create mode 100644 src/util/string.c create mode 100644 src/util/string.h create mode 100644 src/util/thread.h create mode 100644 src/util/thread_posix.c create mode 100644 src/util/thread_win.c diff --git a/resources/NULL b/resources/NULL new file mode 100644 index 0000000..fe3a073 --- /dev/null +++ b/resources/NULL @@ -0,0 +1 @@ +NULL \ No newline at end of file diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..2bd1e3d --- /dev/null +++ b/src/main.c @@ -0,0 +1,8 @@ +#include +#include "util/ipaddr.h" + +int main(int argc, char** argv) { + + + return 0; +} \ No newline at end of file diff --git a/src/sock/tcp.h b/src/sock/tcp.h new file mode 100644 index 0000000..76fd021 --- /dev/null +++ b/src/sock/tcp.h @@ -0,0 +1,58 @@ +#ifndef GLV_SOCK_TCP_H +#define GLV_SOCK_TCP_H + +#ifdef _WIN32 + #define WIN32_LEAN_AND_MEAN + #ifdef __MINGW32__ + #undef _WIN32_WINNT + #define _WIN32_WINNT _WIN32_WINNT_WIN8 + #endif + #include + #include + + typedef SOCKET glv_sock_t; + typedef SOCKADDR_IN glv_addr_t; +#else + #include + #include + #include + #include + #include + #include + #include + #include + + typedef int glv_sock_t; + typedef struct sockaddr_in glv_addr_t; +#endif + +#include +#include "util/ipaddr.h" + +#define GLV_TCP_FLAG_TYPE 1 +#define GLV_TCP_FLAG_NBIO 2 + +#define GLV_TCP_RECV_APPEND 1 +#define GLV_TCP_RECV_BLOCK 2 + +typedef struct { + glv_sock_t socket; + glv_addr_t addr; + uint32_t flags; +} glv_tcp_t; + +glv_tcp_t* glv_tcp_create_server(); +glv_tcp_t* glv_tcp_create_client(); + +int glv_tcp_send(glv_tcp_t* sock, const char* data, unsigned int length); +int glv_tcp_recv(glv_tcp_t* sock, char* data, unsigned int length, int flags); + +int glv_tcp_data_ready(glv_tcp_t* sock); +int glv_tcp_is_open(glv_tcp_t* sock); +int glv_tcp_is_secure(glv_tcp_t* sock); + +ipaddr_t glv_tcp_get_ip(glv_tcp_t* sock); + +void glv_tcp_destroy(glv_tcp_t* sock); + +#endif diff --git a/src/sock/tcp_bsd.c b/src/sock/tcp_bsd.c new file mode 100644 index 0000000..5dff4ab --- /dev/null +++ b/src/sock/tcp_bsd.c @@ -0,0 +1,6 @@ +#ifndef _WIN32 +#include "tcp.h" + + + +#endif \ No newline at end of file diff --git a/src/sock/tcp_win.c b/src/sock/tcp_win.c new file mode 100644 index 0000000..3616d45 --- /dev/null +++ b/src/sock/tcp_win.c @@ -0,0 +1,4 @@ +#ifdef _WIN32 +#include "tcp.h" + +#endif diff --git a/src/util/ipaddr.c b/src/util/ipaddr.c new file mode 100644 index 0000000..6abcd55 --- /dev/null +++ b/src/util/ipaddr.c @@ -0,0 +1,248 @@ +#include "ipaddr.h" + +#define MAX(X,Y) (((X)>(Y))?(X):(Y)) +#define MIN(X,Y) (((X)<(Y))?(X):(Y)) + +const ipaddr_t error_addr = {{0, 0, 0, 0, 0, 0, 0, 0}, -1}; + +ipaddr_t glv_ip_aton(const char* addr) { + const int length = strlen(addr); + ipaddr_t addr_out = {{0, 0, 0, 0, 0, 0, 0, 0}, 128}; + char token[5] = {0, 0, 0, 0, 0}; + int i, j = 0, k = 0, cidr = 0, gap = -2, valid, tmp; + + if(strchr(addr, ':') != NULL && strchr(addr, '.') != NULL) + return error_addr; + if(strcnt(addr, '/') > 1) + return error_addr; + + if(strchr(addr, '.') != NULL) { + if(strcnt(addr, '.') != 3) + return error_addr; + + addr_out.addr[5] = 0xFFFF; + for(i = 0; i < length; ++i) { + if(addr[i] == ' ') + continue; + valid = 0; + + if(isdigit(addr[i])) { + valid = 1; + if(j == 3) + return error_addr; + token[j++] = addr[i]; + } + + if(addr[i] == '.' || addr[i] == '/' || i == length - 1) { + valid = 1; + if(j == 0) + return error_addr; + + token[j] = 0; + if((tmp = atoi(token)) > 255) + return error_addr; + + if(k < 4) { + addr_out.addr[6 + (k / 2)] |= + (tmp << (k % 2 == 0 ? 8 : 0)); + j = 0; + ++k; + } else { + if(tmp > 32) + return error_addr; + addr_out.cidr = tmp + 96; + } + + if(addr[i] == '/' && k != 4) + return error_addr; + } + + if(!valid) + return error_addr; + } + } else { + if(strcnt(addr, ':') > 7) + return error_addr; + + for(i = 0; i < length; ++i) { + if(addr[i] == ' ') + continue; + valid = 0; + + if((isxdigit(addr[i]) && !cidr) || (isdigit(addr[i]) && cidr)) { + valid = 1; + if(j == 4) + return error_addr; + token[j++] = addr[i]; + } + + if(addr[i] == ':' || addr[i] == '/' || i == length - 1) { + valid = 1; + if (j == 0 && + !(k == 0 && i != length - 1 && addr[i + 1] == ':') && + !(i - 2 >= 0 && addr[i] == '/' && + addr[i - 1] == ':' && addr[i - 2] == ':')) + { + return error_addr; + } + + token[j] = 0; + tmp = cidr ? atoi(token) : axtoi(token); + + if(cidr) { + if(tmp > 128) + return error_addr; + addr_out.cidr = tmp; + } else if(j != 0) { + addr_out.addr[k] = tmp; + j = 0; + ++k; + } + + if(addr[i] == '/') + cidr = 1; + if(addr[i] == ':') { + if(cidr) + return error_addr; + if(i == length - 1) + return error_addr; + if(addr[i + 1] == ':') { + if(gap == -2) { + ++i; + gap = k - 1; + continue; + } else + return error_addr; + } + } + } + + if(!valid) + return error_addr; + } + + if(gap > -2) { + for(i = k - 1; i > gap; --i) { + addr_out.addr[7 - (k - 1 - i)] = addr_out.addr[i]; + addr_out.addr[i] = 0; + } + } + } + + return addr_out; +} + +ipaddr_t glv_ip_raw(const uint16_t* addr, uint8_t cidr) { + ipaddr_t addr_out; + memcpy(addr_out.addr, addr, 16); + addr_out.cidr = cidr; + + return addr_out; +} + +int glv_ip_check(const char* addr) { + ipaddr_t test = glv_ip_aton(addr); + return glv_ip_valid(&test); +} + +int glv_ip_compare(const ipaddr_t* lhs, const ipaddr_t* rhs) { + int i = 0, lhs_cidr = lhs->cidr, rhs_cidr = rhs->cidr, mask; + for(i = 0; i < 8; ++i) { + mask = 0xFFFF + & ~((1 << (16 - MIN(16, lhs_cidr))) - 1) + & ~((1 << (16 - MIN(16, rhs_cidr))) - 1); + if(mask == 0) + break; + + if((lhs->addr[i] & mask) != (rhs->addr[i] & mask)) + return 0; + + lhs_cidr = MAX(0, lhs_cidr - 16); + rhs_cidr = MAX(0, rhs_cidr - 16); + } + + return 1; +} + +int glv_ip_identical(const ipaddr_t* lhs, const ipaddr_t* rhs) { + int i; + for(i = 0; i < 8; ++i) + if(lhs->addr[i] != rhs->addr[i]) + return 0; + + return 1; +} + +int glv_ip_isv4(const ipaddr_t* addr) { + return addr->addr[0] == 0 && addr->addr[1] == 0 && + addr->addr[2] == 0 && addr->addr[3] == 0 && + addr->addr[4] == 0 && addr->addr[5] == 0xFFFF; +} + +int glv_ip_valid(const ipaddr_t* addr) { + return addr->cidr <= 128; +} + +char* glv_ip_ntoa(const ipaddr_t* addr) { + if(!glv_ip_isv4(addr)) + return glv_ipv6_ntoa(addr); + if(!glv_ip_valid(addr)) + return NULL; + + char* ip = malloc(18 * sizeof(char)); + if(addr->cidr == 128) { + sprintf(ip, "%i.%i.%i.%i", + (addr->addr[6] >> 8) & 0xFF, + (addr->addr[6]) & 0xFF, + (addr->addr[7] >> 8) & 0xFF, + (addr->addr[7]) & 0xFF + ); + } else { + sprintf(ip, "%i.%i.%i.%i/%i", + (addr->addr[6] >> 8) & 0xFF, + (addr->addr[6]) & 0xFF, + (addr->addr[7] >> 8) & 0xFF, + (addr->addr[7]) & 0xFF, + (addr->cidr - 96) + ); + } + + return ip; +} + +char* glv_ipv6_ntoa(const ipaddr_t* addr) { + if(!glv_ip_valid(addr)) + return NULL; + + char* ip = malloc(43 * sizeof(char)); + int i, jmp = 0, largest_gap_pos = -1, largest_gap_len = 0, curr_gap_len = 0; + + for(i = 0; i < 8; ++i) { + if(addr->addr[i] == 0 && i < 7) + ++curr_gap_len; + else { + if(curr_gap_len > largest_gap_len && curr_gap_len > 1) { + largest_gap_len = curr_gap_len; + largest_gap_pos = i - curr_gap_len; + } + + curr_gap_len = 0; + } + } + + for(i = 0; i < 8; ++i) { + if(i == largest_gap_pos) { + sprintf(ip, (i == 0 ? "::" : "%s:") , ip); + i += largest_gap_len - 1; + jmp = 1; + } else if(!(jmp && i == 7)) { + sprintf(ip, (i == 7 ? "%s%x" : "%s%x:"), ip, addr->addr[i]); + jmp = 0; + } + } + + if(addr->cidr < 128) + sprintf(ip, "%s/%i", ip, addr->cidr); + + return ip; +} \ No newline at end of file diff --git a/src/util/ipaddr.h b/src/util/ipaddr.h new file mode 100644 index 0000000..efd5e34 --- /dev/null +++ b/src/util/ipaddr.h @@ -0,0 +1,29 @@ +#ifndef GLV_UTIL_IPADDR_H +#define GLV_UTIL_IPADDR_H + +#include +#include +#include +#include +#include + +#include "util/string.h" + +typedef struct { + uint16_t addr[8]; + uint8_t cidr; +} ipaddr_t; + +ipaddr_t glv_ip_aton(const char* addr); +ipaddr_t glv_ip_raw(const uint16_t* addr, uint8_t cidr); +int glv_ip_check(const char* addr); + +int glv_ip_compare(const ipaddr_t* lhs, const ipaddr_t* rhs); +int glv_ip_identical(const ipaddr_t* lhs, const ipaddr_t* rhs); +int glv_ip_isv4(const ipaddr_t* addr); +int glv_ip_valid(const ipaddr_t* addr); + +char* glv_ip_ntoa(const ipaddr_t* addr); +char* glv_ipv6_ntoa(const ipaddr_t* addr); + +#endif \ No newline at end of file diff --git a/src/util/string.c b/src/util/string.c new file mode 100644 index 0000000..dd59321 --- /dev/null +++ b/src/util/string.c @@ -0,0 +1,25 @@ +#include "string.h" + +int axtoi(const char* str) { + int value = 0, i; + for(i = 0; i < strlen(str); ++i) { + value *= 16; + if(str[i] >= '0' && str[i] <= '9') + value += str[i] - '0'; + else if(str[i] >= 'a' && str[i] <= 'f') + value += (str[i] - 'a') + 10; + else if(str[i] >= 'A' && str[i] <= 'F') + value += (str[i] - 'A') + 10; + } + + return value; +} + +int strcnt(const char* str, char c) { + int cnt = 0, i; + for(i = 0; i < strlen(str); ++i) + if(str[i] == c) + ++cnt; + + return cnt; +} \ No newline at end of file diff --git a/src/util/string.h b/src/util/string.h new file mode 100644 index 0000000..0b35562 --- /dev/null +++ b/src/util/string.h @@ -0,0 +1,9 @@ +#ifndef GLV_UTIL_STRING_H +#define GLV_UTIL_STRING_H + +#include + +int axtoi(const char* str); +int strcnt(const char* str, char c); + +#endif diff --git a/src/util/thread.h b/src/util/thread.h new file mode 100644 index 0000000..d292474 --- /dev/null +++ b/src/util/thread.h @@ -0,0 +1,37 @@ +#ifndef GLV_UTIL_THREAD_H +#define GLV_UTIL_THREAD_H + +#ifdef _WIN32 + #define WIN32_LEAN_AND_MEAN + #ifdef __MINGW32__ + #undef _WIN32_WINNT + #define _WIN32_WINNT _WIN32_WINNT_WIN8 + #endif + #include + + typedef HANDLE glv_thread_t; + typedef HANDLE glv_mutex_t; +#else + #include + + typedef pthread_t glv_thread_t; + typedef pthread_mutex_t glv_mutex_t; +#endif + +#include +typedef void(*glv_func_t)(void*); + +glv_thread_t* glv_thread_create(glv_func_t func, void* args); +void glv_thread_join(glv_thread_t* thread); +void glv_thread_destroy(glv_thread_t* thread); + +/** END THREAD DECLS **/ +/**********************/ +/** BEGIN MUTX DECLS **/ + +glv_mutex_t* glv_mutex_create(); +void glv_mutex_lock(glv_mutex_t* mutex); +void glv_mutex_unlock(glv_mutex_t* mutex); +void glv_mutex_destroy(glv_mutex_t* mutex); + +#endif diff --git a/src/util/thread_posix.c b/src/util/thread_posix.c new file mode 100644 index 0000000..4afe156 --- /dev/null +++ b/src/util/thread_posix.c @@ -0,0 +1,61 @@ +#ifndef _WIN32 +#include "thread.h" + +typedef struct { + glv_func_t func; + void* args; +} wrapper_t; + +static void* _wrapper_func(void* proxy) { + wrapper_t wrapper = *((wrapper_t*)proxy); + free(proxy); + + wrapper.func(wrapper.args); +} + +glv_thread_t* glv_thread_create(glv_func_t func, void* args) { + wrapper_t* proxy = malloc(sizeof(wrapper_t)); + proxy->func = func; + proxy->args = args; + + glv_thread_t* thread = malloc(sizeof(glv_thread_t)); + if(pthread_create(thread, NULL, _wrapper_func, proxy) == 0) + return thread; + else + return NULL; +} + +void glv_thread_join(glv_thread_t* thread) { + pthread_join(*thread, NULL); +} + +void glv_thread_destroy(glv_thread_t* thread) { + free(thread); +} + +/** END THREAD IMPL **/ +/*********************/ +/** BEGIN MUTX IMPL **/ + +glv_mutex_t* glv_mutex_create() { + glv_mutex_t* mtx = malloc(sizeof(glv_mutex_t)); + if(pthread_mutex_init(mtx, NULL) == 0) + return mtx; + else + return NULL; +} + +void glv_mutex_lock(glv_mutex_t* mutex) { + pthread_mutex_lock(mutex); +} + +void glv_mutex_unlock(glv_mutex_t* mutex) { + pthread_mutex_unlock(mutex); +} + +void glv_mutex_destroy(glv_mutex_t* mutex) { + pthread_mutex_destroy(mutex); + free(mutex); +} + +#endif diff --git a/src/util/thread_win.c b/src/util/thread_win.c new file mode 100644 index 0000000..69619ff --- /dev/null +++ b/src/util/thread_win.c @@ -0,0 +1,44 @@ +#ifdef _WIN32 +#include "thread.h" + +glv_thread_t* glv_thread_create(glv_func_t func, void* args) { + glv_thread_t* thread = malloc(sizeof(glv_thread_t)); + *thread = (glv_thread_t)_beginthread(func, 0, args); + + return thread; +} + +void glv_thread_join(glv_thread_t* thread) { + WaitForSingleObject(*thread, INFINITE); +} + +void glv_thread_destroy(glv_thread_t* thread) { + CloseHandle(*thread); + free(thread); +} + +/** END THREAD IMPL **/ +/*********************/ +/** BEGIN MUTX IMPL **/ + +glv_mutex_t* glv_mutex_create() { + glv_mutex_t* mutex = malloc(sizeof(glv_mutex_t)); + *mutex = CreateMutexA(NULL, NULL, NULL); + + return mutex; +} + +void glv_mutex_lock(glv_mutex_t* mutex) { + WaitForSingleObject(*mutex, INFINITE); +} + +void glv_mutex_unlock(glv_mutex_t* mutex) { + ReleaseMutex(*mutex); +} + +void glv_mutex_destroy(glv_mutex_t* mutex) { + CloseHandle(*mutex); + free(mutex); +} + +#endif \ No newline at end of file