Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

277 lines
6.5 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #if defined( WIN32 )
  10. #if !defined( _X360 )
  11. #include "winsock.h"
  12. #else
  13. #include "winsockx.h"
  14. #endif
  15. #elif defined( POSIX )
  16. #include <sys/socket.h>
  17. #include <netdb.h>
  18. #include <resolv.h>
  19. #include <netinet/in.h>
  20. #include <arpa/inet.h>
  21. #else
  22. #error
  23. #endif
  24. #include "inetapi.h"
  25. #if defined( _X360 )
  26. #include "xbox/xbox_win32stubs.h"
  27. #endif
  28. // memdbgon must be the last include file in a .cpp file!!!
  29. #include <tier0/memdbgon.h>
  30. #pragma warning(disable: 4706) // warning C4706: assignment within conditional expression
  31. //-----------------------------------------------------------------------------
  32. // Purpose: Implements INetAPI
  33. //-----------------------------------------------------------------------------
  34. class CNetAPI : public INetAPI
  35. {
  36. public:
  37. virtual void NetAdrToSockAddr( netadr_t *a, struct sockaddr *s );
  38. virtual void SockAddrToNetAdr( struct sockaddr *s, netadr_t *a );
  39. virtual char *AdrToString( netadr_t *a );
  40. virtual bool StringToAdr( const char *s, netadr_t *a );
  41. virtual void GetSocketAddress( int socket, netadr_t *a );
  42. virtual bool CompareAdr( netadr_t *a, netadr_t *b );
  43. virtual void GetLocalIP(netadr_t *a);
  44. };
  45. // Expose interface
  46. static CNetAPI g_NetAPI;
  47. INetAPI *net = ( INetAPI * )&g_NetAPI;
  48. //-----------------------------------------------------------------------------
  49. // Purpose:
  50. // Input : *a -
  51. // *s -
  52. //-----------------------------------------------------------------------------
  53. void CNetAPI::NetAdrToSockAddr (netadr_t *a, struct sockaddr *s)
  54. {
  55. memset (s, 0, sizeof(*s));
  56. if (a->type == NA_BROADCAST)
  57. {
  58. ((struct sockaddr_in *)s)->sin_family = AF_INET;
  59. ((struct sockaddr_in *)s)->sin_port = a->port;
  60. ((struct sockaddr_in *)s)->sin_addr.s_addr = INADDR_BROADCAST;
  61. }
  62. else if (a->type == NA_IP)
  63. {
  64. ((struct sockaddr_in *)s)->sin_family = AF_INET;
  65. ((struct sockaddr_in *)s)->sin_addr.s_addr = *(int *)&a->ip;
  66. ((struct sockaddr_in *)s)->sin_port = a->port;
  67. }
  68. }
  69. //-----------------------------------------------------------------------------
  70. // Purpose:
  71. // Input : *s -
  72. // *a -
  73. //-----------------------------------------------------------------------------
  74. void CNetAPI::SockAddrToNetAdr( struct sockaddr *s, netadr_t *a )
  75. {
  76. if (s->sa_family == AF_INET)
  77. {
  78. a->type = NA_IP;
  79. *(int *)&a->ip = ((struct sockaddr_in *)s)->sin_addr.s_addr;
  80. a->port = ((struct sockaddr_in *)s)->sin_port;
  81. }
  82. }
  83. //-----------------------------------------------------------------------------
  84. // Purpose:
  85. // Input : *a -
  86. // Output : char
  87. //-----------------------------------------------------------------------------
  88. char *CNetAPI::AdrToString( netadr_t *a )
  89. {
  90. static char s[64];
  91. memset(s, 0, 64);
  92. if ( a )
  93. {
  94. if ( a->type == NA_LOOPBACK )
  95. {
  96. sprintf (s, "loopback");
  97. }
  98. else if ( a->type == NA_IP )
  99. {
  100. sprintf(s, "%i.%i.%i.%i:%i", a->ip[0], a->ip[1], a->ip[2], a->ip[3], ntohs( a->port ) );
  101. }
  102. }
  103. return s;
  104. }
  105. //-----------------------------------------------------------------------------
  106. // Purpose:
  107. // Input : *s -
  108. // *sadr -
  109. // Output : static bool
  110. //-----------------------------------------------------------------------------
  111. static bool StringToSockaddr( const char *s, struct sockaddr *sadr )
  112. {
  113. struct hostent *h;
  114. char *colon;
  115. char copy[128];
  116. struct sockaddr_in *p;
  117. memset (sadr, 0, sizeof(*sadr));
  118. p = ( struct sockaddr_in * )sadr;
  119. p->sin_family = AF_INET;
  120. p->sin_port = 0;
  121. strcpy (copy, s);
  122. // strip off a trailing :port if present
  123. for ( colon = copy ; *colon ; colon++ )
  124. {
  125. if (*colon == ':')
  126. {
  127. // terminate
  128. *colon = 0;
  129. // Start at next character
  130. p->sin_port = htons( ( short )atoi( colon + 1 ) );
  131. }
  132. }
  133. // Numeric IP, no DNS
  134. if ( copy[0] >= '0' && copy[0] <= '9' && strstr( copy, "." ) )
  135. {
  136. *(int *)&p->sin_addr = inet_addr( copy );
  137. }
  138. else
  139. {
  140. // DNS it
  141. if ( !( h = gethostbyname( copy ) ) )
  142. {
  143. return false;
  144. }
  145. // Use first result
  146. *(int *)&p->sin_addr = *(int *)h->h_addr_list[0];
  147. }
  148. return true;
  149. }
  150. //-----------------------------------------------------------------------------
  151. // Purpose:
  152. // Input : *s -
  153. // *a -
  154. // Output : Returns true on success, false on failure.
  155. //-----------------------------------------------------------------------------
  156. bool CNetAPI::StringToAdr( const char *s, netadr_t *a )
  157. {
  158. struct sockaddr sadr;
  159. if ( !strcmp ( s, "localhost" ) )
  160. {
  161. memset ( a, 0, sizeof( *a ) );
  162. a->type = NA_LOOPBACK;
  163. return true;
  164. }
  165. if ( !StringToSockaddr (s, &sadr) )
  166. {
  167. return false;
  168. }
  169. SockAddrToNetAdr( &sadr, a );
  170. return true;
  171. }
  172. //-----------------------------------------------------------------------------
  173. // Purpose: Lookup the IP address for the specified IP socket
  174. // Input : socket -
  175. // *a -
  176. //-----------------------------------------------------------------------------
  177. void CNetAPI::GetSocketAddress( int socket, netadr_t *a )
  178. {
  179. char buff[512];
  180. struct sockaddr_in address;
  181. int namelen;
  182. // int net_error = 0;
  183. memset( a, 0, sizeof( *a ) );
  184. gethostname(buff, 512);
  185. // Ensure that it doesn't overrun the buffer
  186. buff[512-1] = 0;
  187. StringToAdr(buff, a );
  188. namelen = sizeof(address);
  189. if ( getsockname( socket, (struct sockaddr *)&address, (int *)&namelen) == 0 )
  190. {
  191. a->port = address.sin_port;
  192. }
  193. }
  194. //-----------------------------------------------------------------------------
  195. // Purpose: Full IP address compare
  196. // Input : *a -
  197. // *b -
  198. // Output : Returns true on success, false on failure.
  199. //-----------------------------------------------------------------------------
  200. bool CNetAPI::CompareAdr( netadr_t *a, netadr_t *b )
  201. {
  202. if ( a->type != b->type )
  203. {
  204. return false;
  205. }
  206. if ( a->type == NA_LOOPBACK )
  207. {
  208. return true;
  209. }
  210. if ( a->type == NA_IP &&
  211. a->ip[0] == b->ip[0] &&
  212. a->ip[1] == b->ip[1] &&
  213. a->ip[2] == b->ip[2] &&
  214. a->ip[3] == b->ip[3] &&
  215. a->port == b->port )
  216. {
  217. return true;
  218. }
  219. return false;
  220. }
  221. //-----------------------------------------------------------------------------
  222. // Purpose: Full IP address compare
  223. // Input : *a -
  224. // *b -
  225. // Output : Returns true on success, false on failure.
  226. //-----------------------------------------------------------------------------
  227. void CNetAPI::GetLocalIP(netadr_t *a)
  228. {
  229. char s[64];
  230. if(!::gethostname(s,64))
  231. {
  232. struct hostent *localip = ::gethostbyname(s);
  233. if(localip)
  234. {
  235. a->type=NA_IP;
  236. a->port=0;
  237. memcpy(a->ip,localip->h_addr_list[0],4);
  238. }
  239. }
  240. }