diff options
Diffstat (limited to 'ksocket')
-rw-r--r-- | ksocket/berkeley.c | 8 | ||||
-rw-r--r-- | ksocket/berkeley.h | 16 | ||||
-rw-r--r-- | ksocket/helper.hpp | 2 | ||||
-rw-r--r-- | ksocket/ksocket.cpp | 350 | ||||
-rw-r--r-- | ksocket/ksocket.h | 13 | ||||
-rw-r--r-- | ksocket/ksocket.hpp | 233 | ||||
-rw-r--r-- | ksocket/utils.c | 17 | ||||
-rw-r--r-- | ksocket/utils.h | 30 | ||||
-rw-r--r-- | ksocket/wsk.h | 4 |
9 files changed, 656 insertions, 17 deletions
diff --git a/ksocket/berkeley.c b/ksocket/berkeley.c index e72f92e..73ccb79 100644 --- a/ksocket/berkeley.c +++ b/ksocket/berkeley.c @@ -297,14 +297,6 @@ VOID NTAPI KspUtilFreeAddrInfoEx(_In_ PADDRINFOEXW AddrInfo) { // Public functions. ////////////////////////////////////////////////////////////////////////// -uint32_t htonl(uint32_t hostlong) { return __builtin_bswap32(hostlong); } - -uint16_t htons(uint16_t hostshort) { return __builtin_bswap16(hostshort); } - -uint32_t ntohl(uint32_t netlong) { return __builtin_bswap32(netlong); } - -uint16_t ntohs(uint16_t netshort) { return __builtin_bswap16(netshort); } - int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res) { NTSTATUS Status; diff --git a/ksocket/berkeley.h b/ksocket/berkeley.h index b879d3c..1475a89 100644 --- a/ksocket/berkeley.h +++ b/ksocket/berkeley.h @@ -1,6 +1,11 @@ -#pragma once +#ifndef KSOCKET_BERKELEY_H +#define KSOCKET_BERKELEY_H 1 + +#ifdef BUILD_USERMODE +#error "This file should only be included if building for kernel mode! Include <ksocket/ksocket.hpp> wrapper instead." +#endif + #include <ntddk.h> -#include <stdint.h> #include <ksocket/wsk.h> #define socket socket_connection @@ -12,11 +17,6 @@ extern "C" { typedef int socklen_t; typedef intptr_t ssize_t; -uint32_t htonl(uint32_t hostlong); -uint16_t htons(uint16_t hostshort); -uint32_t ntohl(uint32_t netlong); -uint16_t ntohs(uint16_t netshort); - int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res); void freeaddrinfo(struct addrinfo *res); @@ -39,3 +39,5 @@ int closesocket(int sockfd); #ifdef __cplusplus } #endif + +#endif diff --git a/ksocket/helper.hpp b/ksocket/helper.hpp index 153e549..9143b07 100644 --- a/ksocket/helper.hpp +++ b/ksocket/helper.hpp @@ -11,6 +11,8 @@ #include <EASTL/string.h> #include <EASTL/vector.h> +#include <ksocket/utils.h> + #ifndef SOCKET_ERROR #define SOCKET_ERROR -1 #endif diff --git a/ksocket/ksocket.cpp b/ksocket/ksocket.cpp new file mode 100644 index 0000000..ca0625b --- /dev/null +++ b/ksocket/ksocket.cpp @@ -0,0 +1,350 @@ +#include "ksocket.hpp" + +#include <EASTL/type_traits.h> +#include <eastl_compat.hpp> + +#ifdef BUILD_USERMODE +// clang-format off +#include <winsock2.h> +#include <windows.h> +#include <ws2tcpip.h> +// clang-format on +#else +#include <ksocket/berkeley.h> +#include <ksocket/ksocket.h> +#include <ksocket/wsk.h> +#endif +#include <ksocket/utils.h> + +struct KSocketImplCommon { + ADDRESS_FAMILY domain; + int type; + int proto; +}; + +#ifdef BUILD_USERMODE +struct KSocketImpl { + ~KSocketImpl() { closesocket(s); } + + SOCKET s; + KSocketImplCommon c; +}; +#else +struct KSocketImpl { + ~KSocketImpl() { + if (s >= 0) { + closesocket(s); + s = -1; + } + } + + int s = -1; + KSocketImplCommon c; +}; +#endif + +eastl::string KSocketAddress::to_string(bool with_port) const { + if (addr_used != 4) { + return ""; + } + + return ::to_string(addr.u8[0]) + "." + ::to_string(addr.u8[1]) + "." + + ::to_string(addr.u8[2]) + "." + ::to_string(addr.u8[3]) + ":" + + ::to_string(with_port); +} + +void KSocketBuffer::insert_u8(KBuffer::iterator it, uint8_t value) { + buffer.insert(it, value); +} + +void KSocketBuffer::insert_u16(KBuffer::iterator it, uint16_t value) { + uint16_t net_value; + uint8_t insert_value[2]; + + net_value = htons(value); + insert_value[0] = (net_value & 0x00FF) >> 0; + insert_value[1] = (net_value & 0xFF00) >> 8; + buffer.insert(it, insert_value, insert_value + eastl::size(insert_value)); +} + +void KSocketBuffer::insert_u32(KBuffer::iterator it, uint32_t value) { + uint32_t net_value; + uint8_t insert_value[4]; + + net_value = htonl(value); + insert_value[0] = (net_value & 0x000000FF) >> 0; + insert_value[1] = (net_value & 0x0000FF00) >> 8; + insert_value[2] = (net_value & 0x00FF0000) >> 16; + insert_value[3] = (net_value & 0xFF000000) >> 24; + buffer.insert(it, insert_value, insert_value + eastl::size(insert_value)); +} + +void KSocketBuffer::insert_u64(KBuffer::iterator it, uint64_t value) { + uint64_t net_value; + uint8_t insert_value[8]; + + net_value = htonll(value); + insert_value[0] = (net_value & 0x00000000000000FF) >> 0; + insert_value[1] = (net_value & 0x000000000000FF00) >> 8; + insert_value[2] = (net_value & 0x0000000000FF0000) >> 16; + insert_value[3] = (net_value & 0x00000000FF000000) >> 24; + insert_value[4] = (net_value & 0x000000FF00000000) >> 32; + insert_value[5] = (net_value & 0x0000FF0000000000) >> 40; + insert_value[6] = (net_value & 0x00FF000000000000) >> 48; + insert_value[7] = (net_value & 0xFF00000000000000) >> 56; + buffer.insert(it, insert_value, insert_value + eastl::size(insert_value)); +} + +void KSocketBuffer::insert_bytebuffer(KBuffer::iterator it, + const uint8_t bytebuffer[], size_t size) { + buffer.insert(it, bytebuffer, bytebuffer + size); +} + +void KSocketBuffer::consume(size_t amount_bytes) { + if (amount_bytes == 0 || amount_bytes > buffer.size()) + amount_bytes = buffer.size(); + + buffer.erase(buffer.begin(), buffer.begin() + amount_bytes); +} + +eastl::string KSocketBuffer::toHex(eastl::string delim) { + eastl::string str; + char const *const hex = "0123456789ABCDEF"; + char pout[3] = {}; + + for (const auto &input_byte : buffer) { + pout[0] = hex[(input_byte >> 4) & 0xF]; + pout[1] = hex[input_byte & 0xF]; + str += pout; + str += delim; + } + + if (str.length() >= delim.length() && delim.length() > 0) + str.erase(str.length() - delim.length(), delim.length()); + + return str; +} + +KSocket::~KSocket() { + if (m_socket != nullptr) + delete m_socket; +} + +bool KSocket::setup(KSocketType sock_type, int proto) { + int domain, type; + + m_lastError = KSE_SUCCESS; + if (m_socket != nullptr) + delete m_socket; + m_socket = new KSocketImpl(); + if (m_socket == nullptr) { + m_lastError = KSE_SETUP_IMPL_NULL; + return false; + } + + if (KSocket::socketTypeToTuple(sock_type, domain, type) != true) { + m_lastError = KSE_SETUP_INVALID_SOCKET_TYPE; + return false; + } + if (sock_type == KSocketType::KST_STREAM_CLIENT_IP6 || + sock_type == KSocketType::KST_STREAM_SERVER_IP6 || + sock_type == KSocketType::KST_DATAGRAM_IP6) { + m_lastError = KSE_SETUP_UNSUPPORTED_SOCKET_TYPE; + return false; // IPv6 is not supported for now + } + m_socketType = sock_type; + +#ifdef BUILD_USERMODE + m_socket->s = ::socket(domain, type, proto); +#else + // DbgPrint("KSocketType: %d, domain: %d, type: %d, proto: %d", sock_type, + // domain, type, proto); + switch (sock_type) { + case KSocketType::KST_INVALID: + m_lastError = KSE_SETUP_INVALID_SOCKET_TYPE; + return false; + case KSocketType::KST_STREAM_CLIENT_IP4: + case KSocketType::KST_STREAM_CLIENT_IP6: + m_socket->s = ::socket_connection(domain, type, proto); + break; + case KSocketType::KST_STREAM_SERVER_IP4: + case KSocketType::KST_STREAM_SERVER_IP6: + m_socket->s = ::socket_listen(domain, type, proto); + break; + case KSocketType::KST_DATAGRAM_IP4: + case KSocketType::KST_DATAGRAM_IP6: + m_socket->s = ::socket_datagram(domain, type, proto); + break; + } +#endif + m_socket->c.domain = static_cast<ADDRESS_FAMILY>(domain); + m_socket->c.type = type; + m_socket->c.proto = proto; +#ifdef BUILD_USERMODE + return m_socket->s != INVALID_SOCKET; +#else + return m_socket->s >= 0; +#endif +} + +bool KSocket::connect(eastl::string host, eastl::string port) { + struct addrinfo hints = {}; + struct addrinfo *results; + + m_lastError = KSE_SUCCESS; + + if (m_socket == nullptr) + return false; + + if (m_socketType != KSocketType::KST_STREAM_CLIENT_IP4 && + m_socketType != KSocketType::KST_STREAM_CLIENT_IP6) + return false; + + hints.ai_flags |= AI_CANONNAME; + hints.ai_family = m_socket->c.domain; + hints.ai_socktype = m_socket->c.type; + m_lastError = ::getaddrinfo(host.c_str(), port.c_str(), &hints, &results); + if (m_lastError != KSE_SUCCESS) + return false; + + m_lastError = + ::connect(m_socket->s, results->ai_addr, (int)results->ai_addrlen); + freeaddrinfo(results); + return m_lastError == KSE_SUCCESS; +} + +bool KSocket::bind(uint16_t port) { + struct sockaddr_in addr; + + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = INADDR_ANY; + addr.sin_port = htons(port); + + m_lastError = ::bind(m_socket->s, (struct sockaddr *)&addr, sizeof(addr)); + + return m_lastError == KSE_SUCCESS; +} + +bool KSocket::listen(int backlog) { + m_lastError = KSE_SUCCESS; + + if (m_socketType != KSocketType::KST_STREAM_SERVER_IP4 && + m_socketType != KSocketType::KST_STREAM_SERVER_IP6) + return false; + + m_lastError = ::listen(m_socket->s, backlog); + + return m_lastError == KSE_SUCCESS; +} + +bool KSocket::accept(KAcceptThreadCallback thread_callback) { + KAcceptedSocket ka; + struct sockaddr addr; + socklen_t addrlen = sizeof(addr); + + if (m_socket->c.domain != AF_INET) { + m_lastError = KSE_SETUP_UNSUPPORTED_SOCKET_TYPE; + return false; + } + + addr.sa_family = m_socket->c.domain; + ka.m_socket = new KSocketImpl(); + if (ka.m_socket == nullptr) { + m_lastError = KSE_SETUP_IMPL_NULL; + return false; + } + ka.m_socketType = m_socketType; + ka.m_socket->c = m_socket->c; + ka.m_socket->s = ::accept(m_socket->s, &addr, &addrlen); + + if (m_socket->c.domain == AF_INET) { + struct sockaddr_in *addr_in = reinterpret_cast<struct sockaddr_in *>(&addr); + + ka.m_remote.addr_used = 4; + ka.m_remote.addr.u32[0] = addr_in->sin_addr.s_addr; + ka.m_remote.port = addr_in->sin_port; + } else { + m_lastError = KSE_SETUP_UNSUPPORTED_SOCKET_TYPE; + return false; + } + +#ifdef BUILD_USERMODE + if (ka.m_socket->s == INVALID_SOCKET) +#else + if (ka.m_socket->s < 0) +#endif + { + m_lastError = KSE_ACCEPT_FAILED; + return false; + } + + return thread_callback(ka); +} + +bool KSocket::close() { + int rv = closesocket(m_socket->s); + + if (rv == 0) { + m_socket->s = -1; + return true; + } else { + return false; + } +} + +bool KSocket::send() { + m_lastError = KSE_SUCCESS; + + if (m_sendBuffer.size() == 0) + return false; + + m_lastError = + ::send(m_socket->s, reinterpret_cast<const char *>(m_sendBuffer.data()), + m_sendBuffer.size(), 0); + if (m_lastError > 0) { + m_sendBuffer.buffer.erase(m_sendBuffer.begin(), + m_sendBuffer.begin() + m_lastError); + return true; + } + + return false; +} + +bool KSocket::recv(size_t max_recv_size) { + const size_t current_size = m_recvBuffer.size(); + + m_recvBuffer.buffer.resize(current_size + max_recv_size); + m_lastError = ::recv( + m_socket->s, reinterpret_cast<char *>(m_recvBuffer.data() + current_size), + max_recv_size, 0); + if (m_lastError > 0) { + m_recvBuffer.buffer.resize(current_size + m_lastError); + return true; + } + + return false; +} + +bool KSocket::socketTypeToTuple(KSocketType sock_type, int &domain, int &type) { + switch (sock_type) { + case KSocketType::KST_INVALID: + break; + case KSocketType::KST_STREAM_CLIENT_IP4: + case KSocketType::KST_STREAM_SERVER_IP4: + domain = AF_INET; + type = SOCK_STREAM; + return true; + case KSocketType::KST_STREAM_CLIENT_IP6: + case KSocketType::KST_STREAM_SERVER_IP6: + domain = AF_INET6; + type = SOCK_STREAM; + return true; + case KSocketType::KST_DATAGRAM_IP4: + case KSocketType::KST_DATAGRAM_IP6: + domain = AF_INET; + type = SOCK_DGRAM; + return true; + } + + return false; +} diff --git a/ksocket/ksocket.h b/ksocket/ksocket.h index 0a6717e..e44035b 100644 --- a/ksocket/ksocket.h +++ b/ksocket/ksocket.h @@ -1,5 +1,12 @@ -#pragma once -#include "wsk.h" +#ifndef KSOCKET_H +#define KSOCKET_H 1 + +#ifdef BUILD_USERMODE +#error \ + "This file should only be included if building for kernel mode! Include <ksocket/ksocket.hpp> wrapper instead." +#endif + +#include <ksocket/wsk.h> #include <ntddk.h> #define STATUS_UNSUPPORTED_WINDOWS_VERSION \ @@ -97,3 +104,5 @@ KsRecvFrom(_In_ PKSOCKET Socket, _In_ PVOID Buffer, _Inout_ PULONG Length, #ifdef __cplusplus } #endif + +#endif diff --git a/ksocket/ksocket.hpp b/ksocket/ksocket.hpp new file mode 100644 index 0000000..abf03b6 --- /dev/null +++ b/ksocket/ksocket.hpp @@ -0,0 +1,233 @@ +#ifndef KSOCKET_HPP +#define KSOCKET_HPP 1 + +#include <EASTL/functional.h> +#include <EASTL/string.h> +#include <EASTL/vector.h> +#include <cstdint> + +using KBuffer = eastl::vector<uint8_t>; + +struct KSocketImpl; + +enum { + KSE_SUCCESS = 0, + KSE_SETUP_IMPL_NULL = 1, + KSE_SETUP_INVALID_SOCKET_TYPE = 2, + KSE_SETUP_UNSUPPORTED_SOCKET_TYPE = 3, + KSE_ACCEPT_FAILED = 4, +}; + +enum class KSocketType { + KST_INVALID = 0, + KST_STREAM_CLIENT_IP4, + KST_STREAM_SERVER_IP4, + KST_STREAM_CLIENT_IP6, + KST_STREAM_SERVER_IP6, + KST_DATAGRAM_IP4, + KST_DATAGRAM_IP6 +}; + +struct KSocketAddress { + eastl::string to_string(bool with_port = true) const; + uint8_t addr_used = 0; + union { + uint8_t u8[16]; + uint16_t u16[8]; + uint32_t u32[4]; + uint64_t u64[2]; + } addr; + uint16_t port = 0; +}; + +class KAcceptedSocket; +using KAcceptThreadCallback = eastl::function<bool(KAcceptedSocket &accepted)>; + +struct KSocketBuffer { + void insert_i8(KBuffer::iterator it, int8_t value) { + insert_u8(it, static_cast<uint8_t>(value)); + } + void insert_i16(KBuffer::iterator it, int16_t value) { + insert_u16(it, static_cast<uint16_t>(value)); + } + void insert_i32(KBuffer::iterator it, int32_t value) { + insert_u32(it, static_cast<uint32_t>(value)); + } + void insert_i64(KBuffer::iterator it, int64_t value) { + insert_u64(it, static_cast<uint64_t>(value)); + } + + void insert_u8(KBuffer::iterator it, uint8_t value); + void insert_u16(KBuffer::iterator it, uint16_t value); + void insert_u32(KBuffer::iterator it, uint32_t value); + void insert_u64(KBuffer::iterator it, uint64_t value); + + void insert_string(KBuffer::iterator it, const eastl::string &value) { + insert_bytebuffer(it, reinterpret_cast<const uint8_t *>(value.c_str()), + value.length()); + } + void insert_string(KBuffer::iterator it, const char buffer[], size_t size) { + insert_bytebuffer(it, reinterpret_cast<const uint8_t *>(buffer), size); + } + void insert_bytebuffer(KBuffer::iterator it, const void *bytebuffer, + size_t size) { + insert_bytebuffer(it, reinterpret_cast<const uint8_t *>(bytebuffer), size); + } + void insert_bytebuffer(KBuffer::iterator it, const uint8_t bytebuffer[], + size_t size); + + void insert(KBuffer::iterator it, int8_t value) { + insert_u8(it, static_cast<uint8_t>(value)); + } + void insert(KBuffer::iterator it, int16_t value) { + insert_u16(it, static_cast<uint16_t>(value)); + } + void insert(KBuffer::iterator it, int32_t value) { + insert_u32(it, static_cast<uint32_t>(value)); + } + void insert(KBuffer::iterator it, int64_t value) { + insert_u64(it, static_cast<uint64_t>(value)); + } + + void insert(KBuffer::iterator it, uint8_t value) { insert_u8(it, value); } + void insert(KBuffer::iterator it, uint16_t value) { insert_u16(it, value); } + void insert(KBuffer::iterator it, uint32_t value) { insert_u32(it, value); } + void insert(KBuffer::iterator it, uint64_t value) { insert_u64(it, value); } + + void insert(KBuffer::iterator it, const eastl::string value) { + insert_string(it, eastl::move(value)); + } + void insert(KBuffer::iterator it, const char buffer[], size_t size) { + insert_string(it, buffer, size); + } + void insert(KBuffer::iterator it, const char *value) { + insert_string(it, eastl::move(eastl::string(value))); + } + void insert(KBuffer::iterator it, const uint8_t bytebuffer[], size_t size) { + insert_bytebuffer(it, bytebuffer, size); + } + + void consume(size_t amount_bytes = 0); + + eastl::string to_string() { + return eastl::string(reinterpret_cast<const char *>(data()), size()); + } + uint8_t *data() { return buffer.data(); } + size_t size() { return buffer.size(); } + KBuffer::iterator begin() { return buffer.begin(); } + KBuffer::iterator end() { return buffer.end(); } + + eastl::string toHex(eastl::string delim = ":"); + + KBuffer buffer; +}; + +class KSocket { +protected: + KSocket() : m_sendBuffer(), m_recvBuffer() {} + KSocket(const KSocket &) = delete; + ~KSocket(); + bool setup(KSocketType sock_type, int proto = 0); + + bool connect(eastl::string host, eastl::string port); + bool bind(uint16_t port); + bool listen(int backlog); + bool accept(KAcceptThreadCallback thread_callback); + bool close(); + + bool send(); + bool recv(size_t max_recv_size); + +public: + int getLastError() const { return m_lastError; } + + KSocketBuffer &getSendBuffer() { return m_sendBuffer; } + KSocketBuffer &getRecvBuffer() { return m_recvBuffer; } + + static bool socketTypeToTuple(KSocketType sock_type, int &domain, int &type); + +private: + KSocketBuffer m_sendBuffer; + KSocketBuffer m_recvBuffer; + KSocketType m_socketType = KSocketType::KST_INVALID; + KSocketImpl *m_socket = nullptr; + int m_lastError = KSE_SUCCESS; +}; + +class KAcceptedSocket : public KSocket { + friend class KSocket; + +public: + KAcceptedSocket() : KSocket() {} + ~KAcceptedSocket() {} + bool setup(KSocketType sock_type, int proto = 0) = delete; + + bool connect(eastl::string host, eastl::string port) = delete; + bool bind(uint16_t port) = delete; + bool listen(int backlog) = delete; + bool accept(KAcceptThreadCallback thread_callback) = delete; + + bool send() { return KSocket::send(); } + bool recv(size_t max_recv_size = 65535) { + return KSocket::recv(max_recv_size); + } + + int getLastError() { return KSocket::getLastError(); } + + const KSocketAddress &getRemote() { return m_remote; } + +private: + KSocketAddress m_remote; +}; + +class KStreamClientIp4 : public KSocket { +public: + KStreamClientIp4() : KSocket() {} + ~KStreamClientIp4() {} + + bool setup() { + return KSocket::setup(KSocketType::KST_STREAM_CLIENT_IP4, + 6 /* IPPROTO_TCP */); + } + + bool connect(eastl::string host, eastl::string port) { + return KSocket::connect(host, port); + } + bool bind(uint16_t) = delete; + bool listen(int) = delete; + bool accept(KAcceptThreadCallback) = delete; + + bool send() { return KSocket::send(); } + bool recv(size_t max_recv_size = 65535) { + return KSocket::recv(max_recv_size); + } + + int getLastError() { return KSocket::getLastError(); } +}; + +class KStreamServerIp4 : public KSocket { +public: + KStreamServerIp4() : KSocket() {} + ~KStreamServerIp4() {} + + bool setup() { + return KSocket::setup(KSocketType::KST_STREAM_SERVER_IP4, + 6 /* IPPROTO_TCP */); + } + + bool connect(eastl::string host, eastl::string port) = delete; + bool bind(uint16_t port) { return KSocket::bind(port); } + bool listen(int backlog = 16) { return KSocket::listen(backlog); } + bool accept(KAcceptThreadCallback thread_callback) { + return KSocket::accept(thread_callback); + } + + bool send() { return KSocket::send(); } + bool recv(size_t max_recv_size = 65535) { + return KSocket::recv(max_recv_size); + } + + int getLastError() { return KSocket::getLastError(); } +}; + +#endif diff --git a/ksocket/utils.c b/ksocket/utils.c new file mode 100644 index 0000000..1fe26ea --- /dev/null +++ b/ksocket/utils.c @@ -0,0 +1,17 @@ +#include "utils.h" + +uint64_t htonll(uint64_t hostlonglong) { return __builtin_bswap64(hostlonglong); } + +#ifndef BUILD_USERMODE +uint32_t htonl(uint32_t hostlong) { return __builtin_bswap32(hostlong); } + +uint16_t htons(uint16_t hostshort) { return __builtin_bswap16(hostshort); } +#endif + +uint64_t ntohll(uint64_t netlonglong) { return __builtin_bswap64(netlonglong); } + +#ifndef BUILD_USERMODE +uint32_t ntohl(uint32_t netlong) { return __builtin_bswap32(netlong); } + +uint16_t ntohs(uint16_t netshort) { return __builtin_bswap16(netshort); } +#endif diff --git a/ksocket/utils.h b/ksocket/utils.h new file mode 100644 index 0000000..e3c0474 --- /dev/null +++ b/ksocket/utils.h @@ -0,0 +1,30 @@ +#ifndef KSOCKET_UTILS_H +#define KSOCKET_UTILS_H 1 + +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +uint64_t htonll(uint64_t hostlonglong); + +#ifndef BUILD_USERMODE +uint32_t htonl(uint32_t hostlong); + +uint16_t htons(uint16_t hostshort); +#endif + +uint64_t ntohll(uint64_t netlonglong); + +#ifndef BUILD_USERMODE +uint32_t ntohl(uint32_t netlong); + +uint16_t ntohs(uint16_t netshort); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ksocket/wsk.h b/ksocket/wsk.h index ccea103..25d7f06 100644 --- a/ksocket/wsk.h +++ b/ksocket/wsk.h @@ -1,6 +1,10 @@ #ifndef WSK_H #define WSK_H 1 +#ifdef BUILD_USERMODE +#error "This file should only be included if building for kernel mode! Include <ksocket/ksocket.hpp> wrapper instead." +#endif + #include <ntddk.h> #if !defined(__MINGW64__) |