Add some network utility functions for examining a socket's remote IP

This commit is contained in:
baldurk
2016-08-01 22:30:03 +02:00
parent 9dbb37a0cd
commit a995fd0f14
3 changed files with 89 additions and 0 deletions
+27
View File
@@ -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();
};
+31
View File
@@ -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;
}
};
+31
View File
@@ -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;
}
};