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