Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  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_mpath.c
  21.  
  22. #include <dpmi.h>
  23. #include "quakedef.h"
  24. #include "mpdosock.h"
  25.  
  26. short flat_selector;
  27.  
  28. int WSAGetLastError(void);
  29. void sockets_flush(void);
  30.  
  31. extern cvar_t hostname;
  32.  
  33. #define MAXHOSTNAMELEN          256
  34.  
  35. static int net_acceptsocket = -1;               // socket for fielding new connections
  36. static int net_controlsocket;
  37. static int net_broadcastsocket = 0;
  38. //static qboolean ifbcastinit = false;
  39. static struct qsockaddr broadcastaddr;
  40.  
  41. static unsigned long myAddr;
  42.  
  43. #include "net_mp.h"
  44.  
  45.  
  46. //=============================================================================
  47.  
  48. int MPATH_Init (void)
  49. {
  50.         int             i;
  51.         struct hostent *local = NULL;
  52.         char    buff[MAXHOSTNAMELEN];
  53.         struct qsockaddr addr;
  54.         char    *p;
  55.  
  56.         if (COM_CheckParm ("-mpath") == 0)
  57.                 return -1;
  58.  
  59.    flat_selector = __dpmi_allocate_ldt_descriptors(1);
  60.    if (flat_selector == -1) {
  61.       Con_Printf("MPATH_Init: Can't get flat selector\n");
  62.       return -1;
  63.    }
  64.    if (__dpmi_set_segment_base_address(flat_selector, 0) == -1) {
  65.       Con_Printf("MPATH_Init: Can't seg flat base!\n");
  66.       return -1;
  67.    }
  68.    if (__dpmi_set_segment_limit(flat_selector, 0xffffffff) == -1) {
  69.       Con_Printf("MPATH_Init: Can't set segment limit\n");
  70.       return -1;
  71.    }
  72.         // determine my name & address
  73.         if (gethostname(buff, MAXHOSTNAMELEN) == 0)
  74.                 local = gethostbyname(buff);
  75.         if (local)
  76.         {
  77.                 myAddr = *(int *)local->h_addr_list[0];
  78.  
  79.                 // if the quake hostname isn't set, set it to the machine name
  80.                 if (Q_strcmp(hostname.string, "UNNAMED") == 0)
  81.                 {
  82.                         // see if it's a text IP address (well, close enough)
  83.                         for (p = buff; *p; p++)
  84.                                 if ((*p < '0' || *p > '9') && *p != '.')
  85.                                         break;
  86.  
  87.                         // if it is a real name, strip off the domain; we only want the host
  88.                         if (*p)
  89.                         {
  90.                                 for (i = 0; i < 15; i++)
  91.                                         if (buff[i] == '.')
  92.                                                 break;
  93.                                 buff[i] = 0;
  94.                         }
  95.                         Cvar_Set ("hostname", buff);
  96.                 }
  97.         }
  98.  
  99.         if ((net_controlsocket = MPATH_OpenSocket (0)) == -1)
  100.                 Sys_Error("MPATH_Init: Unable to open control socket\n");
  101.  
  102.         ((struct sockaddr_in *)&broadcastaddr)->sin_family = AF_INET;
  103.         ((struct sockaddr_in *)&broadcastaddr)->sin_addr.s_addr = INADDR_BROADCAST;
  104.         ((struct sockaddr_in *)&broadcastaddr)->sin_port = htons(net_hostport);
  105.  
  106.         MPATH_GetSocketAddr (net_controlsocket, &addr);
  107.         Q_strcpy(my_tcpip_address,  MPATH_AddrToString (&addr));
  108.         p = Q_strrchr (my_tcpip_address, ':');
  109.         if (p)
  110.                 *p = 0;
  111.  
  112.         Con_Printf("MPath Initialized\n");
  113.         tcpipAvailable = true;
  114.  
  115.         return net_controlsocket;
  116. }
  117.  
  118. //=============================================================================
  119.  
  120. void MPATH_Shutdown (void)
  121. {
  122.         MPATH_Listen (false);
  123.         MPATH_CloseSocket (net_controlsocket);
  124. }
  125.  
  126. //=============================================================================
  127.  
  128. void MPATH_Listen (qboolean state)
  129. {
  130.         // enable listening
  131.         if (state)
  132.         {
  133.                 if (net_acceptsocket != -1)
  134.                         return;
  135.                 if ((net_acceptsocket = MPATH_OpenSocket (net_hostport)) == -1)
  136.                         Sys_Error ("MPATH_Listen: Unable to open accept socket\n");
  137.                 return;
  138.         }
  139.  
  140.         // disable listening
  141.         if (net_acceptsocket == -1)
  142.                 return;
  143.         MPATH_CloseSocket (net_acceptsocket);
  144.         net_acceptsocket = -1;
  145. }
  146.  
  147. //=============================================================================
  148.  
  149. int MPATH_OpenSocket (int port)
  150. {
  151.         int newsocket;
  152.         struct sockaddr_in address;
  153.         u_long _true = 1;
  154.  
  155.         if ((newsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
  156.                 return -1;
  157.  
  158.         if (ioctlsocket (newsocket, FIONBIO, &_true) == -1)
  159.                 goto ErrorReturn;
  160.  
  161.         address.sin_family = AF_INET;
  162.         address.sin_addr.s_addr = INADDR_ANY;
  163.         address.sin_port = htons(port);
  164.         if( bind (newsocket, (void *)&address, sizeof(address)) == -1)
  165.                 goto ErrorReturn;
  166.  
  167.         return newsocket;
  168.  
  169. ErrorReturn:
  170.         closesocket (newsocket);
  171.         return -1;
  172. }
  173.  
  174. //=============================================================================
  175.  
  176. int MPATH_CloseSocket (int socket)
  177. {
  178.         if (socket == net_broadcastsocket)
  179.                 net_broadcastsocket = 0;
  180.         return closesocket (socket);
  181. }
  182.  
  183.  
  184. //=============================================================================
  185. /*
  186. ============
  187. PartialIPAddress
  188.  
  189. this lets you type only as much of the net address as required, using
  190. the local network components to fill in the rest
  191. ============
  192. */
  193. static int PartialIPAddress (char *in, struct qsockaddr *hostaddr)
  194. {
  195.         char buff[256];
  196.         char *b;
  197.         int addr;
  198.         int num;
  199.         int mask;
  200.         int run;
  201.         int port;
  202.        
  203.         buff[0] = '.';
  204.         b = buff;
  205.         strcpy(buff+1, in);
  206.         if (buff[1] == '.')
  207.                 b++;
  208.  
  209.         addr = 0;
  210.         mask=-1;
  211.         while (*b == '.')
  212.         {
  213.                 b++;
  214.                 num = 0;
  215.                 run = 0;
  216.                 while (!( *b < '0' || *b > '9'))
  217.                 {
  218.                   num = num*10 + *b++ - '0';
  219.                   if (++run > 3)
  220.                         return -1;
  221.                 }
  222.                 if ((*b < '0' || *b > '9') && *b != '.' && *b != ':' && *b != 0)
  223.                         return -1;
  224.                 if (num < 0 || num > 255)
  225.                         return -1;
  226.                 mask<<=8;
  227.                 addr = (addr<<8) + num;
  228.         }
  229.        
  230.         if (*b++ == ':')
  231.                 port = Q_atoi(b);
  232.         else
  233.                 port = net_hostport;
  234.  
  235.         hostaddr->sa_family = AF_INET;
  236.         ((struct sockaddr_in *)hostaddr)->sin_port = htons((short)port);       
  237.         ((struct sockaddr_in *)hostaddr)->sin_addr.s_addr = (myAddr & htonl(mask)) | htonl(addr);
  238.        
  239.         return 0;
  240. }
  241. //=============================================================================
  242.  
  243. int MPATH_Connect (int socket, struct qsockaddr *addr)
  244. {
  245.         return 0;
  246. }
  247.  
  248. //=============================================================================
  249.  
  250. int MPATH_CheckNewConnections (void)
  251. {
  252.         char buf[4];
  253.  
  254.         if (net_acceptsocket == -1)
  255.                 return -1;
  256.  
  257.         if (recvfrom (net_acceptsocket, buf, 4, MSG_PEEK, NULL, NULL) > 0)
  258.                 return net_acceptsocket;
  259.         return -1;
  260. }
  261.  
  262. //=============================================================================
  263.  
  264. int MPATH_Read (int socket, byte *buf, int len, struct qsockaddr *addr)
  265. {
  266.         int addrlen = sizeof (struct qsockaddr);
  267.         int ret;
  268.  
  269.         ret = recvfrom (socket, buf, len, 0, (struct sockaddr *)addr, &addrlen);
  270.         if (ret == -1)
  271.         {
  272.                 int errno = WSAGetLastError();
  273.  
  274.                 if (errno == WSAEWOULDBLOCK || errno == WSAECONNREFUSED)
  275.                         return 0;
  276.  
  277.         }
  278.         return ret;
  279. }
  280.  
  281. //=============================================================================
  282.  
  283. int MPATH_MakeSocketBroadcastCapable (int socket)
  284. {
  285.         int     i = 1;
  286.  
  287.         // make this socket broadcast capable
  288.         if (setsockopt(socket, SOL_SOCKET, SO_BROADCAST, (char *)&i, sizeof(i)) < 0)
  289.                 return -1;
  290.         net_broadcastsocket = socket;
  291.  
  292.         return 0;
  293. }
  294.  
  295. //=============================================================================
  296.  
  297. int MPATH_Broadcast (int socket, byte *buf, int len)
  298. {
  299.         int ret;
  300.  
  301.         if (socket != net_broadcastsocket)
  302.         {
  303.                 if (net_broadcastsocket != 0)
  304.                         Sys_Error("Attempted to use multiple broadcasts sockets\n");
  305.                 ret = MPATH_MakeSocketBroadcastCapable (socket);
  306.                 if (ret == -1)
  307.                 {
  308.                         Con_Printf("Unable to make socket broadcast capable\n");
  309.                         return ret;
  310.                 }
  311.         }
  312.  
  313.         return MPATH_Write (socket, buf, len, &broadcastaddr);
  314. }
  315.  
  316. //=============================================================================
  317.  
  318. int MPATH_Write (int socket, byte *buf, int len, struct qsockaddr *addr)
  319. {
  320.         int ret;
  321.  
  322.         ret = sendto (socket, buf, len, 0, (struct sockaddr *)addr, sizeof(struct qsockaddr));
  323.         if (ret == -1)
  324.                 if (WSAGetLastError() == WSAEWOULDBLOCK)
  325.                         return 0;
  326.  
  327.         sockets_flush();
  328.  
  329.         return ret;
  330. }
  331.  
  332. //=============================================================================
  333.  
  334. char *MPATH_AddrToString (struct qsockaddr *addr)
  335. {
  336.         static char buffer[22];
  337.         int haddr;
  338.  
  339.         haddr = ntohl(((struct sockaddr_in *)addr)->sin_addr.s_addr);
  340.         sprintf(buffer, "%d.%d.%d.%d:%d", (haddr >> 24) & 0xff, (haddr >> 16) & 0xff, (haddr >> 8) & 0xff, haddr & 0xff, ntohs(((struct sockaddr_in *)addr)->sin_port));
  341.         return buffer;
  342. }
  343.  
  344. //=============================================================================
  345.  
  346. int MPATH_StringToAddr (char *string, struct qsockaddr *addr)
  347. {
  348.         int ha1, ha2, ha3, ha4, hp;
  349.         int ipaddr;
  350.  
  351.         sscanf(string, "%d.%d.%d.%d:%d", &ha1, &ha2, &ha3, &ha4, &hp);
  352.         ipaddr = (ha1 << 24) | (ha2 << 16) | (ha3 << 8) | ha4;
  353.  
  354.         addr->sa_family = AF_INET;
  355.         ((struct sockaddr_in *)addr)->sin_addr.s_addr = htonl(ipaddr);
  356.         ((struct sockaddr_in *)addr)->sin_port = htons(hp);
  357.         return 0;
  358. }
  359.  
  360. //=============================================================================
  361.  
  362. int MPATH_GetSocketAddr (int socket, struct qsockaddr *addr)
  363. {
  364.         int addrlen = sizeof(struct qsockaddr);
  365.         unsigned int a;
  366.  
  367.         Q_memset(addr, 0, sizeof(struct qsockaddr));
  368.         getsockname(socket, (struct sockaddr *)addr, &addrlen);
  369.         a = ((struct sockaddr_in *)addr)->sin_addr.s_addr;
  370.         if (a == 0 || a == inet_addr("127.0.0.1"))
  371.                 ((struct sockaddr_in *)addr)->sin_addr.s_addr = myAddr;
  372.  
  373.         return 0;
  374. }
  375.  
  376. //=============================================================================
  377.  
  378. int MPATH_GetNameFromAddr (struct qsockaddr *addr, char *name)
  379. {
  380.         struct hostent *hostentry;
  381.  
  382.         hostentry = gethostbyaddr ((char *)&((struct sockaddr_in *)addr)->sin_addr, sizeof(struct in_addr), AF_INET);
  383.         if (hostentry)
  384.         {
  385.                 Q_strncpy (name, (char *)hostentry->h_name, NET_NAMELEN - 1);
  386.                 return 0;
  387.         }
  388.  
  389.         Q_strcpy (name, MPATH_AddrToString (addr));
  390.         return 0;
  391. }
  392.  
  393. //=============================================================================
  394.  
  395. int MPATH_GetAddrFromName(char *name, struct qsockaddr *addr)
  396. {
  397.         struct hostent *hostentry;
  398.  
  399.         if (name[0] >= '0' && name[0] <= '9')
  400.                 return PartialIPAddress (name, addr);
  401.        
  402.         hostentry = gethostbyname (name);
  403.         if (!hostentry)
  404.                 return -1;
  405.  
  406.         addr->sa_family = AF_INET;
  407.         ((struct sockaddr_in *)addr)->sin_port = htons(net_hostport);  
  408.         ((struct sockaddr_in *)addr)->sin_addr.s_addr = *(int *)hostentry->h_addr_list[0];
  409.  
  410.         return 0;
  411. }
  412.  
  413. //=============================================================================
  414.  
  415. int MPATH_AddrCompare (struct qsockaddr *addr1, struct qsockaddr *addr2)
  416. {
  417.         if (addr1->sa_family != addr2->sa_family)
  418.                 return -1;
  419.  
  420.         if (((struct sockaddr_in *)addr1)->sin_addr.s_addr != ((struct sockaddr_in *)addr2)->sin_addr.s_addr)
  421.                 return -1;
  422.  
  423.         if (((struct sockaddr_in *)addr1)->sin_port != ((struct sockaddr_in *)addr2)->sin_port)
  424.                 return 1;
  425.  
  426.         return 0;
  427. }
  428.  
  429. //=============================================================================
  430.  
  431. int MPATH_GetSocketPort (struct qsockaddr *addr)
  432. {
  433.         return ntohs(((struct sockaddr_in *)addr)->sin_port);
  434. }
  435.  
  436.  
  437. int MPATH_SetSocketPort (struct qsockaddr *addr, int port)
  438. {
  439.         ((struct sockaddr_in *)addr)->sin_port = htons(port);
  440.         return 0;
  441. }
  442.  
  443. //=============================================================================
  444.