summaryrefslogtreecommitdiff
path: root/tracker/common/netapi.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tracker/common/netapi.cpp')
-rw-r--r--tracker/common/netapi.cpp277
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);
+ }
+ }
+}