home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga 14 / MA_Cover_14.iso / source / c / q1source_amy / qw / client / net_wins.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-12-21  |  7.0 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.