Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5131 clevermous 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_wipx.c
21
 
22
#include "quakedef.h"
23
#include "winquake.h"
24
#include 
25
#include "net_wipx.h"
26
 
27
extern cvar_t hostname;
28
 
29
#define MAXHOSTNAMELEN		256
30
 
31
static int net_acceptsocket = -1;		// socket for fielding new connections
32
static int net_controlsocket;
33
static struct qsockaddr broadcastaddr;
34
 
35
extern qboolean winsock_initialized;
36
extern WSADATA		winsockdata;
37
 
38
#define IPXSOCKETS 18
39
static int ipxsocket[IPXSOCKETS];
40
static int sequence[IPXSOCKETS];
41
 
42
//=============================================================================
43
 
44
int WIPX_Init (void)
45
{
46
	int		i;
47
	char	buff[MAXHOSTNAMELEN];
48
	struct qsockaddr addr;
49
	char	*p;
50
	int		r;
51
	WORD	wVersionRequested;
52
 
53
	if (COM_CheckParm ("-noipx"))
54
		return -1;
55
 
56
// make sure LoadLibrary has happened successfully
57
	if (!winsock_lib_initialized)
58
		return -1;
59
 
60
	if (winsock_initialized == 0)
61
	{
62
		wVersionRequested = MAKEWORD(1, 1);
63
 
64
		r = pWSAStartup (MAKEWORD(1, 1), &winsockdata);
65
 
66
		if (r)
67
		{
68
			Con_Printf ("Winsock initialization failed.\n");
69
			return -1;
70
		}
71
	}
72
	winsock_initialized++;
73
 
74
	for (i = 0; i < IPXSOCKETS; i++)
75
		ipxsocket[i] = 0;
76
 
77
	// determine my name & address
78
	if (pgethostname(buff, MAXHOSTNAMELEN) == 0)
79
	{
80
		// if the quake hostname isn't set, set it to the machine name
81
		if (Q_strcmp(hostname.string, "UNNAMED") == 0)
82
		{
83
			// see if it's a text IP address (well, close enough)
84
			for (p = buff; *p; p++)
85
				if ((*p < '0' || *p > '9') && *p != '.')
86
					break;
87
 
88
			// if it is a real name, strip off the domain; we only want the host
89
			if (*p)
90
			{
91
				for (i = 0; i < 15; i++)
92
					if (buff[i] == '.')
93
						break;
94
				buff[i] = 0;
95
			}
96
			Cvar_Set ("hostname", buff);
97
		}
98
	}
99
 
100
	if ((net_controlsocket = WIPX_OpenSocket (0)) == -1)
101
	{
102
		Con_Printf("WIPX_Init: Unable to open control socket\n");
103
		if (--winsock_initialized == 0)
104
			pWSACleanup ();
105
		return -1;
106
	}
107
 
108
	((struct sockaddr_ipx *)&broadcastaddr)->sa_family = AF_IPX;
109
	memset(((struct sockaddr_ipx *)&broadcastaddr)->sa_netnum, 0, 4);
110
	memset(((struct sockaddr_ipx *)&broadcastaddr)->sa_nodenum, 0xff, 6);
111
	((struct sockaddr_ipx *)&broadcastaddr)->sa_socket = htons((unsigned short)net_hostport);
112
 
113
	WIPX_GetSocketAddr (net_controlsocket, &addr);
114
	Q_strcpy(my_ipx_address,  WIPX_AddrToString (&addr));
115
	p = Q_strrchr (my_ipx_address, ':');
116
	if (p)
117
		*p = 0;
118
 
119
	Con_Printf("Winsock IPX Initialized\n");
120
	ipxAvailable = true;
121
 
122
	return net_controlsocket;
123
}
124
 
125
//=============================================================================
126
 
127
void WIPX_Shutdown (void)
128
{
129
	WIPX_Listen (false);
130
	WIPX_CloseSocket (net_controlsocket);
131
	if (--winsock_initialized == 0)
132
		pWSACleanup ();
133
}
134
 
135
//=============================================================================
136
 
137
void WIPX_Listen (qboolean state)
138
{
139
	// enable listening
140
	if (state)
141
	{
142
		if (net_acceptsocket != -1)
143
			return;
144
		if ((net_acceptsocket = WIPX_OpenSocket (net_hostport)) == -1)
145
			Sys_Error ("WIPX_Listen: Unable to open accept socket\n");
146
		return;
147
	}
148
 
149
	// disable listening
150
	if (net_acceptsocket == -1)
151
		return;
152
	WIPX_CloseSocket (net_acceptsocket);
153
	net_acceptsocket = -1;
154
}
155
 
156
//=============================================================================
157
 
158
int WIPX_OpenSocket (int port)
159
{
160
	int handle;
161
	int newsocket;
162
	struct sockaddr_ipx address;
163
	u_long _true = 1;
164
 
165
	for (handle = 0; handle < IPXSOCKETS; handle++)
166
		if (ipxsocket[handle] == 0)
167
			break;
168
	if (handle == IPXSOCKETS)
169
		return -1;
170
 
171
	if ((newsocket = psocket (AF_IPX, SOCK_DGRAM, NSPROTO_IPX)) == INVALID_SOCKET)
172
		return -1;
173
 
174
	if (pioctlsocket (newsocket, FIONBIO, &_true) == -1)
175
		goto ErrorReturn;
176
 
177
	if (psetsockopt(newsocket, SOL_SOCKET, SO_BROADCAST, (char *)&_true, sizeof(_true)) < 0)
178
		goto ErrorReturn;
179
 
180
	address.sa_family = AF_IPX;
181
	memset(address.sa_netnum, 0, 4);
182
	memset(address.sa_nodenum, 0, 6);;
183
	address.sa_socket = htons((unsigned short)port);
184
	if( bind (newsocket, (void *)&address, sizeof(address)) == 0)
185
	{
186
		ipxsocket[handle] = newsocket;
187
		sequence[handle] = 0;
188
		return handle;
189
	}
190
 
191
	Sys_Error ("Winsock IPX bind failed\n");
192
ErrorReturn:
193
	pclosesocket (newsocket);
194
	return -1;
195
}
196
 
197
//=============================================================================
198
 
199
int WIPX_CloseSocket (int handle)
200
{
201
	int socket = ipxsocket[handle];
202
	int ret;
203
 
204
	ret =  pclosesocket (socket);
205
	ipxsocket[handle] = 0;
206
	return ret;
207
}
208
 
209
 
210
//=============================================================================
211
 
212
int WIPX_Connect (int handle, struct qsockaddr *addr)
213
{
214
	return 0;
215
}
216
 
217
//=============================================================================
218
 
219
int WIPX_CheckNewConnections (void)
220
{
221
	unsigned long	available;
222
 
223
	if (net_acceptsocket == -1)
224
		return -1;
225
 
226
	if (pioctlsocket (ipxsocket[net_acceptsocket], FIONREAD, &available) == -1)
227
		Sys_Error ("WIPX: ioctlsocket (FIONREAD) failed\n");
228
	if (available)
229
		return net_acceptsocket;
230
	return -1;
231
}
232
 
233
//=============================================================================
234
 
235
static byte packetBuffer[NET_DATAGRAMSIZE + 4];
236
 
237
int WIPX_Read (int handle, byte *buf, int len, struct qsockaddr *addr)
238
{
239
	int addrlen = sizeof (struct qsockaddr);
240
	int socket = ipxsocket[handle];
241
	int ret;
242
 
243
	ret = precvfrom (socket, packetBuffer, len+4, 0, (struct sockaddr *)addr, &addrlen);
244
	if (ret == -1)
245
	{
246
		int errno = pWSAGetLastError();
247
 
248
		if (errno == WSAEWOULDBLOCK || errno == WSAECONNREFUSED)
249
			return 0;
250
 
251
	}
252
 
253
	if (ret < 4)
254
		return 0;
255
 
256
	// remove sequence number, it's only needed for DOS IPX
257
	ret -= 4;
258
	memcpy(buf, packetBuffer+4, ret);
259
 
260
	return ret;
261
}
262
 
263
//=============================================================================
264
 
265
int WIPX_Broadcast (int handle, byte *buf, int len)
266
{
267
	return WIPX_Write (handle, buf, len, &broadcastaddr);
268
}
269
 
270
//=============================================================================
271
 
272
int WIPX_Write (int handle, byte *buf, int len, struct qsockaddr *addr)
273
{
274
	int socket = ipxsocket[handle];
275
	int ret;
276
 
277
	// build packet with sequence number
278
	*(int *)(&packetBuffer[0]) = sequence[handle];
279
	sequence[handle]++;
280
	memcpy(&packetBuffer[4], buf, len);
281
	len += 4;
282
 
283
	ret = psendto (socket, packetBuffer, len, 0, (struct sockaddr *)addr, sizeof(struct qsockaddr));
284
	if (ret == -1)
285
		if (pWSAGetLastError() == WSAEWOULDBLOCK)
286
			return 0;
287
 
288
	return ret;
289
}
290
 
291
//=============================================================================
292
 
293
char *WIPX_AddrToString (struct qsockaddr *addr)
294
{
295
	static char buf[28];
296
 
297
	sprintf(buf, "%02x%02x%02x%02x:%02x%02x%02x%02x%02x%02x:%u",
298
		((struct sockaddr_ipx *)addr)->sa_netnum[0] & 0xff,
299
		((struct sockaddr_ipx *)addr)->sa_netnum[1] & 0xff,
300
		((struct sockaddr_ipx *)addr)->sa_netnum[2] & 0xff,
301
		((struct sockaddr_ipx *)addr)->sa_netnum[3] & 0xff,
302
		((struct sockaddr_ipx *)addr)->sa_nodenum[0] & 0xff,
303
		((struct sockaddr_ipx *)addr)->sa_nodenum[1] & 0xff,
304
		((struct sockaddr_ipx *)addr)->sa_nodenum[2] & 0xff,
305
		((struct sockaddr_ipx *)addr)->sa_nodenum[3] & 0xff,
306
		((struct sockaddr_ipx *)addr)->sa_nodenum[4] & 0xff,
307
		((struct sockaddr_ipx *)addr)->sa_nodenum[5] & 0xff,
308
		ntohs(((struct sockaddr_ipx *)addr)->sa_socket)
309
		);
310
	return buf;
311
}
312
 
313
//=============================================================================
314
 
315
int WIPX_StringToAddr (char *string, struct qsockaddr *addr)
316
{
317
	int  val;
318
	char buf[3];
319
 
320
	buf[2] = 0;
321
	Q_memset(addr, 0, sizeof(struct qsockaddr));
322
	addr->sa_family = AF_IPX;
323
 
324
#define DO(src,dest)	\
325
	buf[0] = string[src];	\
326
	buf[1] = string[src + 1];	\
327
	if (sscanf (buf, "%x", &val) != 1)	\
328
		return -1;	\
329
	((struct sockaddr_ipx *)addr)->dest = val
330
 
331
	DO(0, sa_netnum[0]);
332
	DO(2, sa_netnum[1]);
333
	DO(4, sa_netnum[2]);
334
	DO(6, sa_netnum[3]);
335
	DO(9, sa_nodenum[0]);
336
	DO(11, sa_nodenum[1]);
337
	DO(13, sa_nodenum[2]);
338
	DO(15, sa_nodenum[3]);
339
	DO(17, sa_nodenum[4]);
340
	DO(19, sa_nodenum[5]);
341
#undef DO
342
 
343
	sscanf (&string[22], "%u", &val);
344
	((struct sockaddr_ipx *)addr)->sa_socket = htons((unsigned short)val);
345
 
346
	return 0;
347
}
348
 
349
//=============================================================================
350
 
351
int WIPX_GetSocketAddr (int handle, struct qsockaddr *addr)
352
{
353
	int socket = ipxsocket[handle];
354
	int addrlen = sizeof(struct qsockaddr);
355
	unsigned int a;
356
 
357
	Q_memset(addr, 0, sizeof(struct qsockaddr));
358
	if(pgetsockname(socket, (struct sockaddr *)addr, &addrlen) != 0)
359
	{
360
		int errno = pWSAGetLastError();
361
	}
362
 
363
	return 0;
364
}
365
 
366
//=============================================================================
367
 
368
int WIPX_GetNameFromAddr (struct qsockaddr *addr, char *name)
369
{
370
	Q_strcpy(name, WIPX_AddrToString(addr));
371
	return 0;
372
}
373
 
374
//=============================================================================
375
 
376
int WIPX_GetAddrFromName(char *name, struct qsockaddr *addr)
377
{
378
	int n;
379
	char buf[32];
380
 
381
	n = Q_strlen(name);
382
 
383
	if (n == 12)
384
	{
385
		sprintf(buf, "00000000:%s:%u", name, net_hostport);
386
		return WIPX_StringToAddr (buf, addr);
387
	}
388
	if (n == 21)
389
	{
390
		sprintf(buf, "%s:%u", name, net_hostport);
391
		return WIPX_StringToAddr (buf, addr);
392
	}
393
	if (n > 21 && n <= 27)
394
		return WIPX_StringToAddr (name, addr);
395
 
396
	return -1;
397
}
398
 
399
//=============================================================================
400
 
401
int WIPX_AddrCompare (struct qsockaddr *addr1, struct qsockaddr *addr2)
402
{
403
	if (addr1->sa_family != addr2->sa_family)
404
		return -1;
405
 
406
	if (*((struct sockaddr_ipx *)addr1)->sa_netnum && *((struct sockaddr_ipx *)addr2)->sa_netnum)
407
		if (memcmp(((struct sockaddr_ipx *)addr1)->sa_netnum, ((struct sockaddr_ipx *)addr2)->sa_netnum, 4) != 0)
408
			return -1;
409
	if (memcmp(((struct sockaddr_ipx *)addr1)->sa_nodenum, ((struct sockaddr_ipx *)addr2)->sa_nodenum, 6) != 0)
410
		return -1;
411
 
412
	if (((struct sockaddr_ipx *)addr1)->sa_socket != ((struct sockaddr_ipx *)addr2)->sa_socket)
413
		return 1;
414
 
415
	return 0;
416
}
417
 
418
//=============================================================================
419
 
420
int WIPX_GetSocketPort (struct qsockaddr *addr)
421
{
422
	return ntohs(((struct sockaddr_ipx *)addr)->sa_socket);
423
}
424
 
425
 
426
int WIPX_SetSocketPort (struct qsockaddr *addr, int port)
427
{
428
	((struct sockaddr_ipx *)addr)->sa_socket = htons((unsigned short)port);
429
	return 0;
430
}
431
 
432
//=============================================================================