mirror of
https://github.com/rehlds/rechecker.git
synced 2024-12-26 20:35:28 +03:00
209 lines
3.9 KiB
C++
209 lines
3.9 KiB
C++
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#ifdef _WIN32
|
|
#include "winsock.h"
|
|
#else
|
|
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
#include <netinet/in.h>
|
|
#include <arpa/inet.h>
|
|
#include <netdb.h>
|
|
#include <unistd.h>
|
|
#endif // _WIN32
|
|
|
|
#include "netapi.h"
|
|
|
|
class CNetAPI: public INetAPI {
|
|
public:
|
|
virtual void NetAdrToSockAddr(netadr_t *a, struct sockaddr *s);
|
|
virtual void SockAddrToNetAdr(struct sockaddr *s, netadr_t *a);
|
|
|
|
virtual char *AdrToString(netadr_t *a);
|
|
virtual bool StringToAdr(const char *s, netadr_t *a);
|
|
|
|
virtual void GetSocketAddress(int socket, netadr_t *a);
|
|
virtual bool CompareAdr(netadr_t *a, netadr_t *b);
|
|
virtual void GetLocalIP(netadr_t *a);
|
|
};
|
|
|
|
// Expose interface
|
|
CNetAPI g_NetAPI;
|
|
INetAPI *net = (INetAPI *)&g_NetAPI;
|
|
|
|
void CNetAPI::NetAdrToSockAddr(netadr_t *a, struct sockaddr *s)
|
|
{
|
|
memset(s, 0, sizeof(*s));
|
|
|
|
if (a->type == NA_BROADCAST)
|
|
{
|
|
((struct sockaddr_in *)s)->sin_family = AF_INET;
|
|
((struct sockaddr_in *)s)->sin_port = a->port;
|
|
((struct sockaddr_in *)s)->sin_addr.s_addr = INADDR_BROADCAST;
|
|
}
|
|
else if (a->type == NA_IP)
|
|
{
|
|
((struct sockaddr_in *)s)->sin_family = AF_INET;
|
|
((struct sockaddr_in *)s)->sin_addr.s_addr = *(int *)&a->ip;
|
|
((struct sockaddr_in *)s)->sin_port = a->port;
|
|
}
|
|
}
|
|
|
|
void CNetAPI::SockAddrToNetAdr(struct sockaddr *s, netadr_t *a)
|
|
{
|
|
if (s->sa_family == AF_INET)
|
|
{
|
|
a->type = NA_IP;
|
|
*(int *)&a->ip = ((struct sockaddr_in *)s)->sin_addr.s_addr;
|
|
a->port = ((struct sockaddr_in *)s)->sin_port;
|
|
}
|
|
}
|
|
|
|
char *CNetAPI::AdrToString(netadr_t *a)
|
|
{
|
|
static char s[64];
|
|
memset(s, 0, sizeof(s));
|
|
|
|
if (a)
|
|
{
|
|
if (a->type == NA_LOOPBACK)
|
|
{
|
|
sprintf(s, "loopback");
|
|
}
|
|
else if (a->type == NA_IP)
|
|
{
|
|
sprintf(s, "%i.%i.%i.%i:%i", a->ip[0], a->ip[1], a->ip[2], a->ip[3], ntohs(a->port));
|
|
}
|
|
}
|
|
|
|
return s;
|
|
}
|
|
|
|
bool StringToSockaddr(const char *s, struct sockaddr *sadr)
|
|
{
|
|
struct hostent *h;
|
|
char *colon;
|
|
char copy[128];
|
|
struct sockaddr_in *p;
|
|
|
|
memset(sadr, 0, sizeof(*sadr));
|
|
|
|
p = (struct sockaddr_in *)sadr;
|
|
p->sin_family = AF_INET;
|
|
p->sin_port = 0;
|
|
|
|
strcpy(copy, s);
|
|
|
|
// strip off a trailing :port if present
|
|
for (colon = copy ; *colon ; colon++)
|
|
{
|
|
if (*colon == ':')
|
|
{
|
|
// terminate
|
|
*colon = '\0';
|
|
|
|
// Start at next character
|
|
p->sin_port = htons((short)atoi(colon + 1));
|
|
}
|
|
}
|
|
|
|
// Numeric IP, no DNS
|
|
if (copy[0] >= '0' && copy[0] <= '9' && strstr(copy, "."))
|
|
{
|
|
*(int *)&p->sin_addr = inet_addr(copy);
|
|
}
|
|
else
|
|
{
|
|
// DNS it
|
|
if (!(h = gethostbyname(copy)))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// Use first result
|
|
*(int *)&p->sin_addr = *(int *)h->h_addr_list[0];
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CNetAPI::StringToAdr(const char *s, netadr_t *a)
|
|
{
|
|
struct sockaddr sadr;
|
|
if (!strcmp(s, "localhost"))
|
|
{
|
|
memset(a, 0, sizeof(*a));
|
|
a->type = NA_LOOPBACK;
|
|
return true;
|
|
}
|
|
|
|
if (!StringToSockaddr(s, &sadr))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
SockAddrToNetAdr(&sadr, a);
|
|
return true;
|
|
}
|
|
|
|
// Lookup the IP address for the specified IP socket
|
|
void CNetAPI::GetSocketAddress(int socket, netadr_t *a)
|
|
{
|
|
char buff[512];
|
|
struct sockaddr_in address;
|
|
int namelen;
|
|
|
|
memset(a, 0, sizeof(*a));
|
|
gethostname(buff, sizeof(buff));
|
|
|
|
// Ensure that it doesn't overrun the buffer
|
|
buff[sizeof buff - 1] = '\0';
|
|
StringToAdr(buff, a);
|
|
|
|
namelen = sizeof(address);
|
|
if (getsockname(socket, (struct sockaddr *)&address, (int *)&namelen) == 0)
|
|
{
|
|
a->port = address.sin_port;
|
|
}
|
|
}
|
|
|
|
bool CNetAPI::CompareAdr(netadr_t *a, netadr_t *b)
|
|
{
|
|
if (a->type != b->type)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (a->type == NA_LOOPBACK)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
if (a->type == NA_IP &&
|
|
a->ip[0] == b->ip[0] &&
|
|
a->ip[1] == b->ip[1] &&
|
|
a->ip[2] == b->ip[2] &&
|
|
a->ip[3] == b->ip[3] &&
|
|
a->port == b->port)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void CNetAPI::GetLocalIP(netadr_t *a)
|
|
{
|
|
char s[64];
|
|
if(!::gethostname(s, 64))
|
|
{
|
|
struct hostent *localip = ::gethostbyname(s);
|
|
if(localip)
|
|
{
|
|
a->type = NA_IP;
|
|
a->port = 0;
|
|
memcpy(a->ip, localip->h_addr_list[0], 4);
|
|
}
|
|
}
|
|
}
|