PageRenderTime 48ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/quakeforge/branches/merged_renderer_0_1/nq/source/net_mp.c

#
C | 479 lines | 313 code | 101 blank | 65 comment | 91 complexity | 2a7c9d66cd05dec1e2dfd3d237b9a64c MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, AGPL-3.0, AGPL-1.0, Unlicense
  1. /*
  2. net_mp.c
  3. @description@
  4. Copyright (C) 1996-1997 Id Software, Inc.
  5. This program is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU General Public License
  7. as published by the Free Software Foundation; either version 2
  8. of the License, or (at your option) any later version.
  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. See the GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to:
  15. Free Software Foundation, Inc.
  16. 59 Temple Place - Suite 330
  17. Boston, MA 02111-1307, USA
  18. $Id: net_mp.c 4238 2001-02-26 06:48:02Z taniwha $
  19. */
  20. #ifdef HAVE_CONFIG_H
  21. # include "config.h"
  22. #endif
  23. #include <dpmi.h>
  24. #include "mpdosock.h"
  25. short flat_selector;
  26. int WSAGetLastError (void);
  27. void sockets_flush (void);
  28. #define MAXHOSTNAMELEN 256
  29. static int net_acceptsocket = -1; // socket for fielding new
  30. // connections
  31. static int net_controlsocket;
  32. static int net_broadcastsocket = 0;
  33. //static qboolean ifbcastinit = false;
  34. static struct qsockaddr broadcastaddr;
  35. static unsigned long myAddr;
  36. #include "net_mp.h"
  37. //=============================================================================
  38. int
  39. MPATH_Init (void)
  40. {
  41. int i;
  42. struct hostent *local = NULL;
  43. char buff[MAXHOSTNAMELEN];
  44. struct qsockaddr addr;
  45. char *p;
  46. if (COM_CheckParm ("-mpath") == 0)
  47. return -1;
  48. flat_selector = __dpmi_allocate_ldt_descriptors (1);
  49. if (flat_selector == -1) {
  50. Con_Printf ("MPATH_Init: Can't get flat selector\n");
  51. return -1;
  52. }
  53. if (__dpmi_set_segment_base_address (flat_selector, 0) == -1) {
  54. Con_Printf ("MPATH_Init: Can't seg flat base!\n");
  55. return -1;
  56. }
  57. if (__dpmi_set_segment_limit (flat_selector, 0xffffffff) == -1) {
  58. Con_Printf ("MPATH_Init: Can't set segment limit\n");
  59. return -1;
  60. }
  61. // determine my name & address
  62. if (gethostname (buff, MAXHOSTNAMELEN) == 0)
  63. local = gethostbyname (buff);
  64. if (local) {
  65. myAddr = *(int *) local->h_addr_list[0];
  66. // if the quake hostname isn't set, set it to the machine name
  67. if (Q_strcmp (hostname->string, "UNNAMED") == 0) {
  68. // see if it's a text IP address (well, close enough)
  69. for (p = buff; *p; p++)
  70. if ((*p < '0' || *p > '9') && *p != '.')
  71. break;
  72. // if it is a real name, strip off the domain; we only want the
  73. // host
  74. if (*p) {
  75. for (i = 0; i < 15; i++)
  76. if (buff[i] == '.')
  77. break;
  78. buff[i] = 0;
  79. }
  80. Cvar_Set (hostname, buff);
  81. }
  82. }
  83. if ((net_controlsocket = MPATH_OpenSocket (0)) == -1)
  84. Sys_Error ("MPATH_Init: Unable to open control socket\n");
  85. ((struct sockaddr_in *) &broadcastaddr)->sin_family = AF_INET;
  86. ((struct sockaddr_in *) &broadcastaddr)->sin_addr.s_addr = INADDR_BROADCAST;
  87. ((struct sockaddr_in *) &broadcastaddr)->sin_port = htons (net_hostport);
  88. MPATH_GetSocketAddr (net_controlsocket, &addr);
  89. Q_strcpy (my_tcpip_address, MPATH_AddrToString (&addr));
  90. p = Q_strrchr (my_tcpip_address, ':');
  91. if (p)
  92. *p = 0;
  93. Con_Printf ("MPath Initialized\n");
  94. tcpipAvailable = true;
  95. return net_controlsocket;
  96. }
  97. //=============================================================================
  98. void
  99. MPATH_Shutdown (void)
  100. {
  101. MPATH_Listen (false);
  102. MPATH_CloseSocket (net_controlsocket);
  103. }
  104. //=============================================================================
  105. void
  106. MPATH_Listen (qboolean state)
  107. {
  108. // enable listening
  109. if (state) {
  110. if (net_acceptsocket != -1)
  111. return;
  112. if ((net_acceptsocket = MPATH_OpenSocket (net_hostport)) == -1)
  113. Sys_Error ("MPATH_Listen: Unable to open accept socket\n");
  114. return;
  115. }
  116. // disable listening
  117. if (net_acceptsocket == -1)
  118. return;
  119. MPATH_CloseSocket (net_acceptsocket);
  120. net_acceptsocket = -1;
  121. }
  122. //=============================================================================
  123. int
  124. MPATH_OpenSocket (int port)
  125. {
  126. int newsocket;
  127. struct sockaddr_in address;
  128. u_long _true = 1;
  129. if ((newsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
  130. return -1;
  131. if (ioctlsocket (newsocket, FIONBIO, &_true) == -1)
  132. goto ErrorReturn;
  133. address.sin_family = AF_INET;
  134. address.sin_addr.s_addr = INADDR_ANY;
  135. address.sin_port = htons (port);
  136. if (bind (newsocket, (void *) &address, sizeof (address)) == -1)
  137. goto ErrorReturn;
  138. return newsocket;
  139. ErrorReturn:
  140. closesocket (newsocket);
  141. return -1;
  142. }
  143. //=============================================================================
  144. int
  145. MPATH_CloseSocket (int socket)
  146. {
  147. if (socket == net_broadcastsocket)
  148. net_broadcastsocket = 0;
  149. return closesocket (socket);
  150. }
  151. //=============================================================================
  152. /*
  153. ============
  154. PartialIPAddress
  155. this lets you type only as much of the net address as required, using
  156. the local network components to fill in the rest
  157. ============
  158. */
  159. static int
  160. PartialIPAddress (char *in, struct qsockaddr *hostaddr)
  161. {
  162. char buff[256];
  163. char *b;
  164. int addr;
  165. int num;
  166. int mask;
  167. int run;
  168. int port;
  169. buff[0] = '.';
  170. b = buff;
  171. strcpy (buff + 1, in);
  172. if (buff[1] == '.')
  173. b++;
  174. addr = 0;
  175. mask = -1;
  176. while (*b == '.') {
  177. b++;
  178. num = 0;
  179. run = 0;
  180. while (!(*b < '0' || *b > '9')) {
  181. num = num * 10 + *b++ - '0';
  182. if (++run > 3)
  183. return -1;
  184. }
  185. if ((*b < '0' || *b > '9') && *b != '.' && *b != ':' && *b != 0)
  186. return -1;
  187. if (num < 0 || num > 255)
  188. return -1;
  189. mask <<= 8;
  190. addr = (addr << 8) + num;
  191. }
  192. if (*b++ == ':')
  193. port = Q_atoi (b);
  194. else
  195. port = net_hostport;
  196. hostaddr->sa_family = AF_INET;
  197. ((struct sockaddr_in *) hostaddr)->sin_port = htons ((short) port);
  198. ((struct sockaddr_in *) hostaddr)->sin_addr.s_addr =
  199. (myAddr & htonl (mask)) | htonl (addr);
  200. return 0;
  201. }
  202. //=============================================================================
  203. int
  204. MPATH_Connect (int socket, struct qsockaddr *addr)
  205. {
  206. return 0;
  207. }
  208. //=============================================================================
  209. int
  210. MPATH_CheckNewConnections (void)
  211. {
  212. char buf[4];
  213. if (net_acceptsocket == -1)
  214. return -1;
  215. if (recvfrom (net_acceptsocket, buf, 4, MSG_PEEK, NULL, NULL) >= 0)
  216. return net_acceptsocket;
  217. return -1;
  218. }
  219. //=============================================================================
  220. int
  221. MPATH_Read (int socket, byte * buf, int len, struct qsockaddr *addr)
  222. {
  223. int addrlen = sizeof (struct qsockaddr);
  224. int ret;
  225. ret = recvfrom (socket, buf, len, 0, (struct sockaddr *) addr, &addrlen);
  226. if (ret == -1) {
  227. int errno = WSAGetLastError ();
  228. if (errno == WSAEWOULDBLOCK || errno == WSAECONNREFUSED)
  229. return 0;
  230. }
  231. return ret;
  232. }
  233. //=============================================================================
  234. int
  235. MPATH_MakeSocketBroadcastCapable (int socket)
  236. {
  237. int i = 1;
  238. // make this socket broadcast capable
  239. if (setsockopt (socket, SOL_SOCKET, SO_BROADCAST, (char *) &i, sizeof (i)) <
  240. 0) return -1;
  241. net_broadcastsocket = socket;
  242. return 0;
  243. }
  244. //=============================================================================
  245. int
  246. MPATH_Broadcast (int socket, byte * buf, int len)
  247. {
  248. int ret;
  249. if (socket != net_broadcastsocket) {
  250. if (net_broadcastsocket != 0)
  251. Sys_Error ("Attempted to use multiple broadcasts sockets\n");
  252. ret = MPATH_MakeSocketBroadcastCapable (socket);
  253. if (ret == -1) {
  254. Con_Printf ("Unable to make socket broadcast capable\n");
  255. return ret;
  256. }
  257. }
  258. return MPATH_Write (socket, buf, len, &broadcastaddr);
  259. }
  260. //=============================================================================
  261. int
  262. MPATH_Write (int socket, byte * buf, int len, struct qsockaddr *addr)
  263. {
  264. int ret;
  265. ret =
  266. sendto (socket, buf, len, 0, (struct sockaddr *) addr,
  267. sizeof (struct qsockaddr));
  268. if (ret == -1)
  269. if (WSAGetLastError () == WSAEWOULDBLOCK)
  270. return 0;
  271. sockets_flush ();
  272. return ret;
  273. }
  274. //=============================================================================
  275. char *
  276. MPATH_AddrToString (struct qsockaddr *addr)
  277. {
  278. static char buffer[22];
  279. int haddr;
  280. haddr = ntohl (((struct sockaddr_in *) addr)->sin_addr.s_addr);
  281. snprintf (buffer, sizeof (buffer), "%d.%d.%d.%d:%d", (haddr >> 24) & 0xff,
  282. (haddr >> 16) & 0xff, (haddr >> 8) & 0xff, haddr & 0xff,
  283. ntohs (((struct sockaddr_in *) addr)->sin_port));
  284. return buffer;
  285. }
  286. //=============================================================================
  287. int
  288. MPATH_StringToAddr (char *string, struct qsockaddr *addr)
  289. {
  290. int ha1, ha2, ha3, ha4, hp;
  291. int ipaddr;
  292. sscanf (string, "%d.%d.%d.%d:%d", &ha1, &ha2, &ha3, &ha4, &hp);
  293. ipaddr = (ha1 << 24) | (ha2 << 16) | (ha3 << 8) | ha4;
  294. addr->sa_family = AF_INET;
  295. ((struct sockaddr_in *) addr)->sin_addr.s_addr = htonl (ipaddr);
  296. ((struct sockaddr_in *) addr)->sin_port = htons (hp);
  297. return 0;
  298. }
  299. //=============================================================================
  300. int
  301. MPATH_GetSocketAddr (int socket, struct qsockaddr *addr)
  302. {
  303. int addrlen = sizeof (struct qsockaddr);
  304. unsigned int a;
  305. Q_memset (addr, 0, sizeof (struct qsockaddr));
  306. getsockname (socket, (struct sockaddr *) addr, &addrlen);
  307. a = ((struct sockaddr_in *) addr)->sin_addr.s_addr;
  308. if (a == 0 || a == inet_addr ("127.0.0.1"))
  309. ((struct sockaddr_in *) addr)->sin_addr.s_addr = myAddr;
  310. return 0;
  311. }
  312. //=============================================================================
  313. int
  314. MPATH_GetNameFromAddr (struct qsockaddr *addr, char *name)
  315. {
  316. struct hostent *hostentry;
  317. hostentry =
  318. gethostbyaddr ((char *) &((struct sockaddr_in *) addr)->sin_addr,
  319. sizeof (struct in_addr), AF_INET);
  320. if (hostentry) {
  321. Q_strncpy (name, (char *) hostentry->h_name, NET_NAMELEN - 1);
  322. return 0;
  323. }
  324. Q_strcpy (name, MPATH_AddrToString (addr));
  325. return 0;
  326. }
  327. //=============================================================================
  328. int
  329. MPATH_GetAddrFromName (char *name, struct qsockaddr *addr)
  330. {
  331. struct hostent *hostentry;
  332. if (name[0] >= '0' && name[0] <= '9')
  333. return PartialIPAddress (name, addr);
  334. hostentry = gethostbyname (name);
  335. if (!hostentry)
  336. return -1;
  337. addr->sa_family = AF_INET;
  338. ((struct sockaddr_in *) addr)->sin_port = htons (net_hostport);
  339. ((struct sockaddr_in *) addr)->sin_addr.s_addr =
  340. *(int *) hostentry->h_addr_list[0];
  341. return 0;
  342. }
  343. //=============================================================================
  344. int
  345. MPATH_AddrCompare (struct qsockaddr *addr1, struct qsockaddr *addr2)
  346. {
  347. if (addr1->sa_family != addr2->sa_family)
  348. return -1;
  349. if (((struct sockaddr_in *) addr1)->sin_addr.s_addr !=
  350. ((struct sockaddr_in *) addr2)->sin_addr.s_addr)
  351. return -1;
  352. if (((struct sockaddr_in *) addr1)->sin_port !=
  353. ((struct sockaddr_in *) addr2)->sin_port)
  354. return 1;
  355. return 0;
  356. }
  357. //=============================================================================
  358. int
  359. MPATH_GetSocketPort (struct qsockaddr *addr)
  360. {
  361. return ntohs (((struct sockaddr_in *) addr)->sin_port);
  362. }
  363. int
  364. MPATH_SetSocketPort (struct qsockaddr *addr, int port)
  365. {
  366. ((struct sockaddr_in *) addr)->sin_port = htons (port);
  367. return 0;
  368. }
  369. //=============================================================================