diff options
Diffstat (limited to 'tracker/common/netapi.cpp')
| -rw-r--r-- | tracker/common/netapi.cpp | 277 |
1 files changed, 277 insertions, 0 deletions
diff --git a/tracker/common/netapi.cpp b/tracker/common/netapi.cpp new file mode 100644 index 0000000..914f5f3 --- /dev/null +++ b/tracker/common/netapi.cpp @@ -0,0 +1,277 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= +#include <stdio.h> +#include <stdlib.h> +#if defined( WIN32 ) +#if !defined( _X360 ) +#include "winsock.h" +#else +#include "winsockx.h" +#endif +#elif defined( POSIX ) +#include <sys/socket.h> +#include <netdb.h> +#include <resolv.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#else +#error +#endif +#include "inetapi.h" + +#if defined( _X360 ) +#include "xbox/xbox_win32stubs.h" +#endif + +// memdbgon must be the last include file in a .cpp file!!! +#include <tier0/memdbgon.h> +#pragma warning(disable: 4706) // warning C4706: assignment within conditional expression + +//----------------------------------------------------------------------------- +// Purpose: Implements INetAPI +//----------------------------------------------------------------------------- +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 +static CNetAPI g_NetAPI; +INetAPI *net = ( INetAPI * )&g_NetAPI; + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *a - +// *s - +//----------------------------------------------------------------------------- +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; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *s - +// *a - +//----------------------------------------------------------------------------- +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; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *a - +// Output : char +//----------------------------------------------------------------------------- +char *CNetAPI::AdrToString( netadr_t *a ) +{ + static char s[64]; + + memset(s, 0, 64); + + 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; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *s - +// *sadr - +// Output : static bool +//----------------------------------------------------------------------------- +static 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; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *s - +// *a - +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +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; +} + +//----------------------------------------------------------------------------- +// Purpose: Lookup the IP address for the specified IP socket +// Input : socket - +// *a - +//----------------------------------------------------------------------------- +void CNetAPI::GetSocketAddress( int socket, netadr_t *a ) +{ + char buff[512]; + struct sockaddr_in address; + int namelen; +// int net_error = 0; + + memset( a, 0, sizeof( *a ) ); + gethostname(buff, 512); + // Ensure that it doesn't overrun the buffer + buff[512-1] = 0; + + StringToAdr(buff, a ); + + namelen = sizeof(address); + if ( getsockname( socket, (struct sockaddr *)&address, (int *)&namelen) == 0 ) + { + a->port = address.sin_port; + } +} + +//----------------------------------------------------------------------------- +// Purpose: Full IP address compare +// Input : *a - +// *b - +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +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; +} + +//----------------------------------------------------------------------------- +// Purpose: Full IP address compare +// Input : *a - +// *b - +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- + +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); + } + } +} |