home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / quakeworld_src / client / net_wins.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-06-17  |  7.2 KB  |  329 lines

  1. /*
  2. Copyright (C) 1996-1997 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */
  20. // net_wins.c
  21.  
  22. #include "quakedef.h"
  23. #include "winquake.h"
  24.  
  25. netadr_t  net_local_adr;
  26.  
  27. netadr_t  net_from;
  28. sizebuf_t net_message;
  29. int     net_socket;
  30.  
  31. #define MAX_UDP_PACKET  (MAX_MSGLEN*2)  // one more than msg + header
  32. byte    net_message_buffer[MAX_UDP_PACKET];
  33.  
  34. WSADATA   winsockdata;
  35.  
  36. //=============================================================================
  37.  
  38. void NetadrToSockadr (netadr_t *a, struct sockaddr_in *s)
  39. {
  40.   memset (s, 0, sizeof(*s));
  41.   s->sin_family = AF_INET;
  42.  
  43.   *(int *)&s->sin_addr = *(int *)&a->ip;
  44.   s->sin_port = a->port;
  45. }
  46.  
  47. void SockadrToNetadr (struct sockaddr_in *s, netadr_t *a)
  48. {
  49.   *(int *)&a->ip = *(int *)&s->sin_addr;
  50.   a->port = s->sin_port;
  51. }
  52.  
  53. qboolean  NET_CompareBaseAdr (netadr_t a, netadr_t b)
  54. {
  55.   if (a.ip[0] == b.ip[0] && a.ip[1] == b.ip[1] && a.ip[2] == b.ip[2] && a.ip[3] == b.ip[3])
  56.     return true;
  57.   return false;
  58. }
  59.  
  60. qboolean  NET_CompareAdr (netadr_t a, netadr_t b)
  61. {
  62.   if (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)
  63.     return true;
  64.   return false;
  65. }
  66.  
  67. char  *NET_AdrToString (netadr_t a)
  68. {
  69.   static  char  s[64];
  70.   
  71.   sprintf (s, "%i.%i.%i.%i:%i", a.ip[0], a.ip[1], a.ip[2], a.ip[3], ntohs(a.port));
  72.  
  73.   return s;
  74. }
  75.  
  76. char  *NET_BaseAdrToString (netadr_t a)
  77. {
  78.   static  char  s[64];
  79.   
  80.   sprintf (s, "%i.%i.%i.%i", a.ip[0], a.ip[1], a.ip[2], a.ip[3]);
  81.  
  82.   return s;
  83. }
  84.  
  85. /*
  86. =============
  87. NET_StringToAdr
  88.  
  89. idnewt
  90. idnewt:28000
  91. 192.246.40.70
  92. 192.246.40.70:28000
  93. =============
  94. */
  95. qboolean  NET_StringToAdr (char *s, netadr_t *a)
  96. {
  97.   struct hostent  *h;
  98.   struct sockaddr_in sadr;
  99.   char  *colon;
  100.   char  copy[128];
  101.   
  102.   
  103.   memset (&sadr, 0, sizeof(sadr));
  104.   sadr.sin_family = AF_INET;
  105.   
  106.   sadr.sin_port = 0;
  107.  
  108.   strcpy (copy, s);
  109.   // strip off a trailing :port if present
  110.   for (colon = copy ; *colon ; colon++)
  111.     if (*colon == ':')
  112.     {
  113.       *colon = 0;
  114.       sadr.sin_port = htons((short)atoi(colon+1));  
  115.     }
  116.   
  117.   if (copy[0] >= '0' && copy[0] <= '9')
  118.   {
  119.     *(int *)&sadr.sin_addr = inet_addr(copy);
  120.   }
  121.   else
  122.   {
  123.     if ((h = gethostbyname(copy)) == 0)
  124.       return 0;
  125.     *(int *)&sadr.sin_addr = *(int *)h->h_addr_list[0];
  126.   }
  127.   
  128.   SockadrToNetadr (&sadr, a);
  129.  
  130.   return true;
  131. }
  132.  
  133. // Returns true if we can't bind the address locally--in other words, 
  134. // the IP is NOT one of our interfaces.
  135. qboolean NET_IsClientLegal(netadr_t *adr)
  136. {
  137.   struct sockaddr_in sadr;
  138.   int newsocket;
  139.  
  140. #if 0
  141.   if (adr->ip[0] == 127)
  142.     return false; // no local connections period
  143.  
  144.   NetadrToSockadr (adr, &sadr);
  145.  
  146.   if ((newsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
  147.     Sys_Error ("NET_IsClientLegal: socket:", strerror(errno));
  148.  
  149.   sadr.sin_port = 0;
  150.  
  151.   if( bind (newsocket, (void *)&sadr, sizeof(sadr)) == -1) 
  152.   {
  153.     // It is not a local address
  154.     close(newsocket);
  155.     return true;
  156.   }
  157.   close(newsocket);
  158.   return false;
  159. #else
  160.   return true;
  161. #endif
  162. }
  163.  
  164. //=============================================================================
  165.  
  166. qboolean NET_GetPacket (void)
  167. {
  168.   int   ret;
  169.   struct sockaddr_in  from;
  170.   int   fromlen;
  171.  
  172.   fromlen = sizeof(from);
  173.   ret = recvfrom (net_socket, (char *)net_message_buffer, sizeof(net_message_buffer), 0, (struct sockaddr *)&from, &fromlen);
  174.   SockadrToNetadr (&from, &net_from);
  175.  
  176.   if (ret == -1)
  177.   {
  178.     int errno = WSAGetLastError();
  179.  
  180.     if (errno == WSAEWOULDBLOCK)
  181.       return false;
  182.     if (errno == WSAEMSGSIZE) {
  183.       Con_Printf ("Warning:  Oversize packet from %s\n",
  184.         NET_AdrToString (net_from));
  185.       return false;
  186.     }
  187.  
  188.  
  189.     Sys_Error ("NET_GetPacket: %s", strerror(errno));
  190.   }
  191.  
  192.   net_message.cursize = ret;
  193.   if (ret == sizeof(net_message_buffer) )
  194.   {
  195.     Con_Printf ("Oversize packet from %s\n", NET_AdrToString (net_from));
  196.     return false;
  197.   }
  198.  
  199.   return ret;
  200. }
  201.  
  202. //=============================================================================
  203.  
  204. void NET_SendPacket (int length, void *data, netadr_t to)
  205. {
  206.   int ret;
  207.   struct sockaddr_in  addr;
  208.  
  209.   NetadrToSockadr (&to, &addr);
  210.  
  211.   ret = sendto (net_socket, data, length, 0, (struct sockaddr *)&addr, sizeof(addr) );
  212.   if (ret == -1)
  213.   {
  214.     int err = WSAGetLastError();
  215.  
  216. // wouldblock is silent
  217.         if (err == WSAEWOULDBLOCK)
  218.           return;
  219.  
  220. #ifndef SERVERONLY
  221.     if (err == WSAEADDRNOTAVAIL)
  222.       Con_DPrintf("NET_SendPacket Warning: %i\n", err);
  223.     else
  224. #endif
  225.       Con_Printf ("NET_SendPacket ERROR: %i\n", errno);
  226.   }
  227. }
  228.  
  229. //=============================================================================
  230.  
  231. int UDP_OpenSocket (int port)
  232. {
  233.   int newsocket;
  234.   struct sockaddr_in address;
  235.   unsigned long _true = true;
  236.   int i;
  237.  
  238.   if ((newsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
  239.     Sys_Error ("UDP_OpenSocket: socket:", strerror(errno));
  240.  
  241.   if (ioctlsocket (newsocket, FIONBIO, &_true) == -1)
  242.     Sys_Error ("UDP_OpenSocket: ioctl FIONBIO:", strerror(errno));
  243.  
  244.   address.sin_family = AF_INET;
  245. //ZOID -- check for interface binding option
  246.   if ((i = COM_CheckParm("-ip")) != 0 && i < com_argc) {
  247.     address.sin_addr.s_addr = inet_addr(com_argv[i+1]);
  248.     Con_Printf("Binding to IP Interface Address of %s\n",
  249.         inet_ntoa(address.sin_addr));
  250.   } else
  251.     address.sin_addr.s_addr = INADDR_ANY;
  252.  
  253.   if (port == PORT_ANY)
  254.     address.sin_port = 0;
  255.   else
  256.     address.sin_port = htons((short)port);
  257.   if( bind (newsocket, (void *)&address, sizeof(address)) == -1)
  258.     Sys_Error ("UDP_OpenSocket: bind: %s", strerror(errno));
  259.  
  260.   return newsocket;
  261. }
  262.  
  263. void NET_GetLocalAddress (void)
  264. {
  265.   char  buff[512];
  266.   struct sockaddr_in  address;
  267.   int   namelen;
  268.  
  269.   gethostname(buff, 512);
  270.   buff[512-1] = 0;
  271.  
  272.   NET_StringToAdr (buff, &net_local_adr);
  273.  
  274.   namelen = sizeof(address);
  275.   if (getsockname (net_socket, (struct sockaddr *)&address, &namelen) == -1)
  276.     Sys_Error ("NET_Init: getsockname:", strerror(errno));
  277.   net_local_adr.port = address.sin_port;
  278.  
  279.   Con_Printf("IP address %s\n", NET_AdrToString (net_local_adr) );
  280. }
  281.  
  282. /*
  283. ====================
  284. NET_Init
  285. ====================
  286. */
  287. void NET_Init (int port)
  288. {
  289.   WORD  wVersionRequested; 
  290.   int   r;
  291.  
  292.   wVersionRequested = MAKEWORD(1, 1); 
  293.  
  294.   r = WSAStartup (MAKEWORD(1, 1), &winsockdata);
  295.  
  296.   if (r)
  297.     Sys_Error ("Winsock initialization failed.");
  298.  
  299.   //
  300.   // open the single socket to be used for all communications
  301.   //
  302.   net_socket = UDP_OpenSocket (port);
  303.  
  304.   //
  305.   // init the message buffer
  306.   //
  307.   net_message.maxsize = sizeof(net_message_buffer);
  308.   net_message.data = net_message_buffer;
  309.  
  310.   //
  311.   // determine my name & address
  312.   //
  313.   NET_GetLocalAddress ();
  314.  
  315.   Con_Printf("UDP Initialized\n");
  316. }
  317.  
  318. /*
  319. ====================
  320. NET_Shutdown
  321. ====================
  322. */
  323. void  NET_Shutdown (void)
  324. {
  325.   closesocket (net_socket);
  326.   WSACleanup ();
  327. }
  328.  
  329.