|
|
1.1 root 1: // net_wins.c
2:
3: #include "../qcommon/qcommon.h"
4:
5: #include <unistd.h>
6: #include <sys/socket.h>
7: #include <netinet/in.h>
8: #include <netdb.h>
9: #include <sys/param.h>
10: #include <sys/ioctl.h>
11: #include <sys/uio.h>
12: #include <errno.h>
13: #include <sys/filio.h>
14:
15: #ifdef NeXT
16: #include <libc.h>
17: #endif
18:
19: netadr_t net_local_adr;
20:
21: #define LOOPBACK 0x7f000001
22:
23: #define MAX_LOOPBACK 4
24:
25: typedef struct
26: {
27: byte data[MAX_MSGLEN];
28: int datalen;
29: } loopmsg_t;
30:
31: typedef struct
32: {
33: loopmsg_t msgs[MAX_LOOPBACK];
34: int get, send;
35: } loopback_t;
36:
37: loopback_t loopbacks[2];
38: int ip_sockets[2];
39: int ipx_sockets[2];
40:
41: int NET_Socket (char *net_interface, int port);
42: char *NET_ErrorString (void);
43:
44: //=============================================================================
45:
46: void NetadrToSockadr (netadr_t *a, struct sockaddr_in *s)
47: {
48: memset (s, 0, sizeof(*s));
49:
50: if (a->type == NA_BROADCAST)
51: {
52: s->sin_family = AF_INET;
53:
54: s->sin_port = a->port;
55: *(int *)&s->sin_addr = -1;
56: }
57: else if (a->type == NA_IP)
58: {
59: s->sin_family = AF_INET;
60:
61: *(int *)&s->sin_addr = *(int *)&a->ip;
62: s->sin_port = a->port;
63: }
64: }
65:
66: void SockadrToNetadr (struct sockaddr_in *s, netadr_t *a)
67: {
68: *(int *)&a->ip = *(int *)&s->sin_addr;
69: a->port = s->sin_port;
70: a->type = NA_IP;
71: }
72:
73:
74: qboolean NET_CompareAdr (netadr_t a, netadr_t b)
75: {
76: 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)
77: return true;
78: return false;
79: }
80:
81: /*
82: ===================
83: NET_CompareBaseAdr
84:
85: Compares without the port
86: ===================
87: */
88: qboolean NET_CompareBaseAdr (netadr_t a, netadr_t b)
89: {
90: if (a.type != b.type)
91: return false;
92:
93: if (a.type == NA_LOOPBACK)
94: return true;
95:
96: if (a.type == NA_IP)
97: {
98: 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])
99: return true;
100: return false;
101: }
102:
103: if (a.type == NA_IPX)
104: {
105: if ((memcmp(a.ipx, b.ipx, 10) == 0))
106: return true;
107: return false;
108: }
109: }
110:
111: char *NET_AdrToString (netadr_t a)
112: {
113: static char s[64];
114:
115: Com_sprintf (s, sizeof(s), "%i.%i.%i.%i:%i", a.ip[0], a.ip[1], a.ip[2], a.ip[3], ntohs(a.port));
116:
117: return s;
118: }
119:
120: char *NET_BaseAdrToString (netadr_t a)
121: {
122: static char s[64];
123:
124: Com_sprintf (s, sizeof(s), "%i.%i.%i.%i", a.ip[0], a.ip[1], a.ip[2], a.ip[3]);
125:
126: return s;
127: }
128:
129: /*
130: =============
131: NET_StringToAdr
132:
133: localhost
134: idnewt
135: idnewt:28000
136: 192.246.40.70
137: 192.246.40.70:28000
138: =============
139: */
140: qboolean NET_StringToSockaddr (char *s, struct sockaddr *sadr)
141: {
142: struct hostent *h;
143: char *colon;
144: char copy[128];
145:
146: memset (sadr, 0, sizeof(*sadr));
147: ((struct sockaddr_in *)sadr)->sin_family = AF_INET;
148:
149: ((struct sockaddr_in *)sadr)->sin_port = 0;
150:
151: strcpy (copy, s);
152: // strip off a trailing :port if present
153: for (colon = copy ; *colon ; colon++)
154: if (*colon == ':')
155: {
156: *colon = 0;
157: ((struct sockaddr_in *)sadr)->sin_port = htons((short)atoi(colon+1));
158: }
159:
160: if (copy[0] >= '0' && copy[0] <= '9')
161: {
162: *(int *)&((struct sockaddr_in *)sadr)->sin_addr = inet_addr(copy);
163: }
164: else
165: {
166: if (! (h = gethostbyname(copy)) )
167: return 0;
168: *(int *)&((struct sockaddr_in *)sadr)->sin_addr = *(int *)h->h_addr_list[0];
169: }
170:
171: return true;
172: }
173:
174: /*
175: =============
176: NET_StringToAdr
177:
178: localhost
179: idnewt
180: idnewt:28000
181: 192.246.40.70
182: 192.246.40.70:28000
183: =============
184: */
185: qboolean NET_StringToAdr (char *s, netadr_t *a)
186: {
187: struct sockaddr_in sadr;
188:
189: if (!strcmp (s, "localhost"))
190: {
191: memset (a, 0, sizeof(*a));
192: a->type = NA_LOOPBACK;
193: return true;
194: }
195:
196: if (!NET_StringToSockaddr (s, (struct sockaddr *)&sadr))
197: return false;
198:
199: SockadrToNetadr (&sadr, a);
200:
201: return true;
202: }
203:
204:
205: qboolean NET_IsLocalAddress (netadr_t adr)
206: {
207: return NET_CompareAdr (adr, net_local_adr);
208: }
209:
210: /*
211: =============================================================================
212:
213: LOOPBACK BUFFERS FOR LOCAL PLAYER
214:
215: =============================================================================
216: */
217:
218: qboolean NET_GetLoopPacket (netsrc_t sock, netadr_t *net_from, sizebuf_t *net_message)
219: {
220: int i;
221: loopback_t *loop;
222:
223: loop = &loopbacks[sock];
224:
225: if (loop->send - loop->get > MAX_LOOPBACK)
226: loop->get = loop->send - MAX_LOOPBACK;
227:
228: if (loop->get >= loop->send)
229: return false;
230:
231: i = loop->get & (MAX_LOOPBACK-1);
232: loop->get++;
233:
234: memcpy (net_message->data, loop->msgs[i].data, loop->msgs[i].datalen);
235: net_message->cursize = loop->msgs[i].datalen;
236: *net_from = net_local_adr;
237: return true;
238:
239: }
240:
241:
242: void NET_SendLoopPacket (netsrc_t sock, int length, void *data, netadr_t to)
243: {
244: int i;
245: loopback_t *loop;
246:
247: loop = &loopbacks[sock^1];
248:
249: i = loop->send & (MAX_LOOPBACK-1);
250: loop->send++;
251:
252: memcpy (loop->msgs[i].data, data, length);
253: loop->msgs[i].datalen = length;
254: }
255:
256: //=============================================================================
257:
258: qboolean NET_GetPacket (netsrc_t sock, netadr_t *net_from, sizebuf_t *net_message)
259: {
260: int ret;
261: struct sockaddr_in from;
262: int fromlen;
263: int net_socket;
264: int protocol;
265: int err;
266:
267: if (NET_GetLoopPacket (sock, net_from, net_message))
268: return true;
269:
270: for (protocol = 0 ; protocol < 2 ; protocol++)
271: {
272: if (protocol == 0)
273: net_socket = ip_sockets[sock];
274: else
275: net_socket = ipx_sockets[sock];
276:
277: if (!net_socket)
278: continue;
279:
280: fromlen = sizeof(from);
281: ret = recvfrom (net_socket, net_message->data, net_message->maxsize
282: , 0, (struct sockaddr *)&from, &fromlen);
283: if (ret == -1)
284: {
285: err = errno;
286:
287: if (err == EWOULDBLOCK || err == ECONNREFUSED)
288: continue;
289: Com_Printf ("NET_GetPacket: %s", NET_ErrorString());
290: continue;
291: }
292:
293: if (ret == net_message->maxsize)
294: {
295: Com_Printf ("Oversize packet from %s\n", NET_AdrToString (*net_from));
296: continue;
297: }
298:
299: net_message->cursize = ret;
300: SockadrToNetadr (&from, net_from);
301: return true;
302: }
303:
304: return false;
305: }
306:
307: //=============================================================================
308:
309: void NET_SendPacket (netsrc_t sock, int length, void *data, netadr_t to)
310: {
311: int ret;
312: struct sockaddr_in addr;
313: int net_socket;
314:
315: if ( to.type == NA_LOOPBACK )
316: {
317: NET_SendLoopPacket (sock, length, data, to);
318: return;
319: }
320:
321: if (to.type == NA_BROADCAST)
322: {
323: net_socket = ip_sockets[sock];
324: if (!net_socket)
325: return;
326: }
327: else if (to.type == NA_IP)
328: {
329: net_socket = ip_sockets[sock];
330: if (!net_socket)
331: return;
332: }
333: else if (to.type == NA_IPX)
334: {
335: net_socket = ipx_sockets[sock];
336: if (!net_socket)
337: return;
338: }
339: else if (to.type == NA_BROADCAST_IPX)
340: {
341: net_socket = ipx_sockets[sock];
342: if (!net_socket)
343: return;
344: }
345: else
346: Com_Error (ERR_FATAL, "NET_SendPacket: bad address type");
347:
348: NetadrToSockadr (&to, &addr);
349:
350: ret = sendto (net_socket, data, length, 0, (struct sockaddr *)&addr, sizeof(addr) );
351: if (ret == -1)
352: {
353: Com_Printf ("NET_SendPacket ERROR: %i\n", NET_ErrorString());
354: }
355: }
356:
357:
358: //=============================================================================
359:
360:
361:
362:
363: /*
364: ====================
365: NET_OpenIP
366: ====================
367: */
368: void NET_OpenIP (void)
369: {
370: cvar_t *port, *ip;
371:
372: port = Cvar_Get ("port", va("%i", PORT_SERVER), CVAR_NOSET);
373: ip = Cvar_Get ("ip", "localhost", CVAR_NOSET);
374:
375: if (!ip_sockets[NS_SERVER])
376: ip_sockets[NS_SERVER] = NET_Socket (ip->string, port->value);
377: if (!ip_sockets[NS_CLIENT])
378: ip_sockets[NS_CLIENT] = NET_Socket (ip->string, PORT_ANY);
379: }
380:
381: /*
382: ====================
383: NET_OpenIPX
384: ====================
385: */
386: void NET_OpenIPX (void)
387: {
388: }
389:
390:
391: /*
392: ====================
393: NET_Config
394:
395: A single player game will only use the loopback code
396: ====================
397: */
398: void NET_Config (qboolean multiplayer)
399: {
400: int i;
401:
402: if (!multiplayer)
403: { // shut down any existing sockets
404: for (i=0 ; i<2 ; i++)
405: {
406: if (ip_sockets[i])
407: {
408: close (ip_sockets[i]);
409: ip_sockets[i] = 0;
410: }
411: if (ipx_sockets[i])
412: {
413: close (ipx_sockets[i]);
414: ipx_sockets[i] = 0;
415: }
416: }
417: }
418: else
419: { // open sockets
420: NET_OpenIP ();
421: NET_OpenIPX ();
422: }
423: }
424:
425:
426: //===================================================================
427:
428:
429: /*
430: ====================
431: NET_Init
432: ====================
433: */
434: void NET_Init (void)
435: {
436: }
437:
438:
439: /*
440: ====================
441: NET_Socket
442: ====================
443: */
444: int NET_Socket (char *net_interface, int port)
445: {
446: int newsocket;
447: struct sockaddr_in address;
448: qboolean _true = true;
449: int i = 1;
450:
451: if ((newsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
452: {
453: Com_Printf ("ERROR: UDP_OpenSocket: socket:", NET_ErrorString());
454: return 0;
455: }
456:
457: // make it non-blocking
458: if (ioctl (newsocket, FIONBIO, &_true) == -1)
459: {
460: Com_Printf ("ERROR: UDP_OpenSocket: ioctl FIONBIO:%s\n", NET_ErrorString());
461: return 0;
462: }
463:
464: // make it broadcast capable
465: if (setsockopt(newsocket, SOL_SOCKET, SO_BROADCAST, (char *)&i, sizeof(i)) == -1)
466: {
467: Com_Printf ("ERROR: UDP_OpenSocket: setsockopt SO_BROADCAST:%s\n", NET_ErrorString());
468: return 0;
469: }
470:
471: if (!net_interface || !net_interface[0] || !stricmp(net_interface, "localhost"))
472: address.sin_addr.s_addr = INADDR_ANY;
473: else
474: NET_StringToSockaddr (net_interface, (struct sockaddr *)&address);
475:
476: if (port == PORT_ANY)
477: address.sin_port = 0;
478: else
479: address.sin_port = htons((short)port);
480:
481: address.sin_family = AF_INET;
482:
483: if( bind (newsocket, (void *)&address, sizeof(address)) == -1)
484: {
485: Com_Printf ("ERROR: UDP_OpenSocket: bind: %s\n", NET_ErrorString());
486: close (newsocket);
487: return 0;
488: }
489:
490: return newsocket;
491: }
492:
493:
494: /*
495: ====================
496: NET_Shutdown
497: ====================
498: */
499: void NET_Shutdown (void)
500: {
501: NET_Config (false); // close sockets
502: }
503:
504:
505: /*
506: ====================
507: NET_ErrorString
508: ====================
509: */
510: char *NET_ErrorString (void)
511: {
512: int code;
513:
514: code = errno;
515: return strerror (code);
516: }
517:
518: // sleeps msec or until net socket is ready
519: void NET_Sleep(int msec)
520: {
521: struct timeval timeout;
522: fd_set fdset;
523: extern cvar_t *dedicated;
524: extern qboolean stdin_active;
525:
526: if (!ip_sockets[NS_SERVER] || (dedicated && !dedicated->value))
527: return; // we're not a server, just run full speed
528:
529: FD_ZERO(&fdset);
530: if (stdin_active)
531: FD_SET(0, &fdset); // stdin is processed too
532: FD_SET(ip_sockets[NS_SERVER], &fdset); // network socket
533: timeout.tv_sec = msec/1000;
534: timeout.tv_usec = (msec%1000)*1000;
535: select(ip_sockets[NS_SERVER]+1, &fdset, NULL, NULL, &timeout);
536: }
537:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.