From a995fd0f14dfb605fc09b2cb15bd906d886b057f Mon Sep 17 00:00:00 2001 From: baldurk Date: Mon, 1 Aug 2016 22:30:03 +0200 Subject: [PATCH] Add some network utility functions for examining a socket's remote IP --- renderdoc/os/os_specific.h | 27 ++++++++++++++++++++++++ renderdoc/os/posix/posix_network.cpp | 31 ++++++++++++++++++++++++++++ renderdoc/os/win32/win32_network.cpp | 31 ++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+) diff --git a/renderdoc/os/os_specific.h b/renderdoc/os/os_specific.h index 25b3daab1..e1d7d2abb 100644 --- a/renderdoc/os/os_specific.h +++ b/renderdoc/os/os_specific.h @@ -154,6 +154,8 @@ public: Socket *AcceptClient(bool wait); + uint32_t GetRemoteIP() const; + bool IsRecvDataWaiting(); bool SendDataBlocking(const void *buf, uint32_t length); @@ -166,6 +168,31 @@ private: Socket *CreateServerSocket(const char *addr, uint16_t port, int queuesize); Socket *CreateClientSocket(const char *host, uint16_t port, int timeoutMS); +// ip is packed in HOST byte order +inline uint32_t GetIPOctet(uint32_t ip, uint32_t octet) +{ + uint32_t shift = (3 - octet) * 8; + uint32_t mask = 0xff << shift; + + return (ip & mask) >> shift; +} + +// returns ip packed in HOST byte order (ie. little endian) +inline uint32_t MakeIP(uint32_t a, uint32_t b, uint32_t c, uint32_t d) +{ + return ((a & 0xff) << 24) | ((b & 0xff) << 16) | ((c & 0xff) << 8) | ((d & 0xff) << 0); +} + +// checks if `ip` matches the given `range` and subnet `mask` +inline bool MatchIPMask(uint32_t ip, uint32_t range, uint32_t mask) +{ + return (ip & mask) == (range & mask); +} + +// parses the null-terminated string at 'str' for CIDR notation IP range +// aaa.bbb.ccc.ddd/nn +bool ParseIPRangeCIDR(const char *str, uint32_t &ip, uint32_t &mask); + void Init(); void Shutdown(); }; diff --git a/renderdoc/os/posix/posix_network.cpp b/renderdoc/os/posix/posix_network.cpp index aef9ff4f3..492ab3152 100644 --- a/renderdoc/os/posix/posix_network.cpp +++ b/renderdoc/os/posix/posix_network.cpp @@ -69,6 +69,16 @@ bool Socket::Connected() const return (int)socket != -1; } +uint32_t Socket::GetRemoteIP() const +{ + sockaddr_in addr = {}; + socklen_t len = sizeof(addr); + + getpeername((int)socket, (sockaddr *)&addr, &len); + + return ntohl(addr.sin_addr.s_addr); +} + Socket *Socket::AcceptClient(bool wait) { do @@ -335,4 +345,25 @@ Socket *CreateClientSocket(const char *host, uint16_t port, int timeoutMS) RDCWARN("Failed to connect to %S:%d", host, port); return NULL; } + +bool ParseIPRangeCIDR(const char *str, uint32_t &ip, uint32_t &mask) +{ + uint32_t a = 0, b = 0, c = 0, d = 0, num = 0; + + int ret = sscanf(str, "%u.%u.%u.%u/%u", &a, &b, &c, &d, &num); + + ip = MakeIP(a, b, c, d); + + if(num == 0) + { + mask = 0; + } + else + { + num = 32 - num; + mask = ((~0U) >> num) << num; + } + + return ret == 5; +} }; diff --git a/renderdoc/os/win32/win32_network.cpp b/renderdoc/os/win32/win32_network.cpp index 0f18bbe4d..6078d9b83 100644 --- a/renderdoc/os/win32/win32_network.cpp +++ b/renderdoc/os/win32/win32_network.cpp @@ -64,6 +64,16 @@ bool Socket::Connected() const return (SOCKET)socket != INVALID_SOCKET; } +uint32_t Socket::GetRemoteIP() const +{ + sockaddr_in addr = {}; + socklen_t len = sizeof(addr); + + getpeername((SOCKET)socket, (sockaddr *)&addr, &len); + + return ntohl(addr.sin_addr.s_addr); +} + Socket *Socket::AcceptClient(bool wait) { do @@ -350,4 +360,25 @@ Socket *CreateClientSocket(const char *host, uint16_t port, int timeoutMS) RDCWARN("Failed to connect to %s:%d", host, port); return NULL; } + +bool ParseIPRangeCIDR(const char *str, uint32_t &ip, uint32_t &mask) +{ + uint32_t a = 0, b = 0, c = 0, d = 0, num = 0; + + int ret = sscanf_s(str, "%u.%u.%u.%u/%u", &a, &b, &c, &d, &num); + + ip = MakeIP(a, b, c, d); + + if(num == 0) + { + mask = 0; + } + else + { + num = 32 - num; + mask = ((~0U) >> num) << num; + } + + return ret == 5; +} };