1 /*
2    Copyright (C) 1999-2006 Id Software, Inc. and contributors.
3    For a list of contributors, see the accompanying CONTRIBUTORS file.
4 
5    This file is part of GtkRadiant.
6 
7    GtkRadiant is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11 
12    GtkRadiant is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with GtkRadiant; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20  */
21 
22 //===========================================================================
23 //
24 // Name:         l_net_wins.c
25 // Function:     WinSock
26 // Programmer:   MrElusive
27 // Last update:  TTimo: cross-platform version, l_net library
28 // Tab Size:     2
29 // Notes:
30 //===========================================================================
31 
32 //#include <windows.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include "l_net.h"
37 #include "l_net_wins.h"
38 
39 #include <sys/types.h>
40 #include <sys/socket.h>
41 #include <sys/ioctl.h>
42 #include <netinet/in.h>
43 #include <netinet/tcp.h>
44 #include <arpa/inet.h>
45 #include <errno.h>
46 #include <netdb.h>
47 #include <unistd.h>
48 #include <stdarg.h>
49 #include <stdio.h>
50 #define SOCKET_ERROR -1
51 #define INVALID_SOCKET -1
52 
53 #define WinError WinPrint
54 
55 #define qtrue   1
56 #define qfalse  0
57 
58 #define ioctlsocket ioctl
59 #define closesocket close
60 
WSAGetLastError()61 int WSAGetLastError(){
62 	return errno;
63 }
64 
65 /*
66    typedef struct tag_error_struct
67    {
68     int     errnum;
69     LPSTR   errstr;
70    } ERROR_STRUCT;
71  */
72 
73 typedef struct tag_error_struct
74 {
75 	int errnum;
76 	const char *errstr;
77 } ERROR_STRUCT;
78 
79 #define NET_NAMELEN         64
80 
81 static char my_tcpip_address[NET_NAMELEN];
82 
83 #define DEFAULTnet_hostport 26000
84 
85 #define MAXHOSTNAMELEN      256
86 
87 static int net_acceptsocket = -1;       // socket for fielding new connections
88 static int net_controlsocket;
89 static int net_hostport;                // udp port number for acceptsocket
90 static int net_broadcastsocket = 0;
91 //static qboolean ifbcastinit = qfalse;
92 //static struct sockaddr_s broadcastaddr;
93 static struct sockaddr_s broadcastaddr;
94 
95 static unsigned long myAddr;
96 
97 ERROR_STRUCT errlist[] = {
98 	{EACCES,"EACCES - The address is protected, user is not root"},
99 	{EAGAIN,"EAGAIN - Operation on non-blocking socket that cannot return immediatly"},
100 	{EBADF, "EBADF - sockfd is not a valid descriptor"},
101 	{EFAULT, "EFAULT - The parameter is not in a writable part of the user address space"},
102 	{EINVAL,"EINVAL - The socket is already bound to an address"},
103 	{ENOBUFS,"ENOBUFS - not enough memory"},
104 	{ENOMEM, "ENOMEM - not enough memory"},
105 	{ENOTCONN, "ENOTCONN - not connected"},
106 	{ENOTSOCK,"ENOTSOCK - Argument is file descriptor not a socket"},
107 	{EOPNOTSUPP,"ENOTSUPP - The referenced socket is not of type SOCK_STREAM"},
108 	{EPERM, "EPERM - Firewall rules forbid connection"},
109 	{-1, NULL}
110 };
111 
112 //===========================================================================
113 //
114 // Parameter:				-
115 // Returns:					-
116 // Changes Globals:		-
117 //===========================================================================
WINS_ErrorMessage(int error)118 const char *WINS_ErrorMessage( int error ){
119 	int search = 0;
120 
121 	if ( !error ) {
122 		return "No error occurred";
123 	}
124 
125 	for ( search = 0; errlist[search].errstr; search++ )
126 	{
127 		if ( error == errlist[search].errnum ) {
128 			return errlist[search].errstr;
129 		}
130 	}  //end for
131 
132 	return "Unknown error";
133 } //end of the function WINS_ErrorMessage
134 //===========================================================================
135 //
136 // Parameter:				-
137 // Returns:					-
138 // Changes Globals:		-
139 //===========================================================================
WINS_Init(void)140 int WINS_Init( void ){
141 	int i;
142 	struct hostent *local;
143 	char buff[MAXHOSTNAMELEN];
144 	struct sockaddr_s addr;
145 	char    *p;
146 /*
147    linux doesn't have anything to initialize for the net
148    "Windows .. built for the internet .. the internet .. built with unix"
149  */
150 #if 0
151 	WORD wVersionRequested;
152 
153 	wVersionRequested = MAKEWORD( 2, 2 );
154 
155 	r = WSAStartup( wVersionRequested, &winsockdata );
156 
157 	if ( r ) {
158 		WinPrint( "Winsock initialization failed.\n" );
159 		return -1;
160 	}
161 #endif
162 	/*
163 	   i = COM_CheckParm ("-udpport");
164 	   if (i == 0)*/
165 	net_hostport = DEFAULTnet_hostport;
166 	/*
167 	   else if (i < com_argc-1)
168 	    net_hostport = Q_atoi (com_argv[i+1]);
169 	   else
170 	    Sys_Error ("WINS_Init: you must specify a number after -udpport");
171 	 */
172 
173 	// determine my name & address
174 	gethostname( buff, MAXHOSTNAMELEN );
175 	local = gethostbyname( buff );
176 	if(local && local->h_addr_list && local->h_addr_list[0])
177 		myAddr = *(int *)local->h_addr_list[0];
178 	else
179 		myAddr = inet_addr("127.0.0.1");
180 
181 	// if the quake hostname isn't set, set it to the machine name
182 //	if (Q_strcmp(hostname.string, "UNNAMED") == 0)
183 	{
184 		// see if it's a text IP address (well, close enough)
185 		for ( p = buff; *p; p++ )
186 			if ( ( *p < '0' || *p > '9' ) && *p != '.' ) {
187 				break;
188 			}
189 
190 		// if it is a real name, strip off the domain; we only want the host
191 		if ( *p ) {
192 			for ( i = 0; i < 15; i++ )
193 				if ( buff[i] == '.' ) {
194 					break;
195 				}
196 			buff[i] = 0;
197 		}
198 //		Cvar_Set ("hostname", buff);
199 	}
200 
201 	//++timo WTF is that net_controlsocket? it's sole purpose is to retrieve the local IP?
202 	if ( ( net_controlsocket = WINS_OpenSocket( 0 ) ) == SOCKET_ERROR ) {
203 		WinError( "WINS_Init: Unable to open control socket\n" );
204 	}
205 
206 	( (struct sockaddr_in *)&broadcastaddr )->sin_family = AF_INET;
207 	( (struct sockaddr_in *)&broadcastaddr )->sin_addr.s_addr = INADDR_BROADCAST;
208 	( (struct sockaddr_in *)&broadcastaddr )->sin_port = htons( (u_short)net_hostport );
209 
210 	WINS_GetSocketAddr( net_controlsocket, &addr );
211 	strcpy( my_tcpip_address,  WINS_AddrToString( &addr ) );
212 	p = strrchr( my_tcpip_address, ':' );
213 	if ( p ) {
214 		*p = 0;
215 	}
216 	WinPrint( "Winsock Initialized\n" );
217 
218 	return net_controlsocket;
219 } //end of the function WINS_Init
220 //===========================================================================
221 //
222 // Parameter:				-
223 // Returns:					-
224 // Changes Globals:		-
225 //===========================================================================
WINS_MyAddress(void)226 char *WINS_MyAddress( void ){
227 	return my_tcpip_address;
228 } //end of the function WINS_MyAddress
229 //===========================================================================
230 //
231 // Parameter:				-
232 // Returns:					-
233 // Changes Globals:		-
234 //===========================================================================
WINS_Shutdown(void)235 void WINS_Shutdown( void ){
236 	//WINS_Listen(0);
237 	WINS_CloseSocket( net_controlsocket );
238 //	WSACleanup();
239 	//
240 	//WinPrint("Winsock Shutdown\n");
241 } //end of the function WINS_Shutdown
242 //===========================================================================
243 //
244 // Parameter:				-
245 // Returns:					-
246 // Changes Globals:		-
247 //===========================================================================
248 /*
249    void WINS_Listen(int state)
250    {
251     // enable listening
252     if (state)
253     {
254         if (net_acceptsocket != -1)
255             return;
256         if ((net_acceptsocket = WINS_OpenSocket (net_hostport)) == -1)
257             WinError ("WINS_Listen: Unable to open accept socket\n");
258         return;
259     }
260 
261     // disable listening
262     if (net_acceptsocket == -1)
263         return;
264     WINS_CloseSocket (net_acceptsocket);
265     net_acceptsocket = -1;
266    } //end of the function WINS_Listen*/
267 //===========================================================================
268 //
269 // Parameter:				-
270 // Returns:					-
271 // Changes Globals:		-
272 //===========================================================================
WINS_OpenSocket(int port)273 int WINS_OpenSocket( int port ){
274 	int newsocket;
275 	struct sockaddr_in address;
276 	u_long _true = 1;
277 
278 	if ( ( newsocket = socket( PF_INET, SOCK_DGRAM, IPPROTO_UDP ) ) == SOCKET_ERROR ) {
279 		WinPrint( "WINS_OpenSocket: %s\n", WINS_ErrorMessage( WSAGetLastError() ) );
280 		return -1;
281 	} //end if
282 
283 	if ( ioctlsocket( newsocket, FIONBIO, &_true ) == SOCKET_ERROR ) {
284 		WinPrint( "WINS_OpenSocket: %s\n", WINS_ErrorMessage( WSAGetLastError() ) );
285 		closesocket( newsocket );
286 		return -1;
287 	} //end if
288 
289 	memset( (char *) &address, 0, sizeof( address ) );
290 	address.sin_family = AF_INET;
291 	address.sin_addr.s_addr = INADDR_ANY;
292 	address.sin_port = htons( (u_short)port );
293 	if ( bind( newsocket, (void *)&address, sizeof( address ) ) == -1 ) {
294 		WinPrint( "WINS_OpenSocket: %s\n", WINS_ErrorMessage( WSAGetLastError() ) );
295 		closesocket( newsocket );
296 		return -1;
297 	} //end if
298 
299 	return newsocket;
300 } //end of the function WINS_OpenSocket
301 //===========================================================================
302 //
303 // Parameter:				-
304 // Returns:					-
305 // Changes Globals:		-
306 //===========================================================================
WINS_OpenReliableSocket(int port)307 int WINS_OpenReliableSocket( int port ){
308 	int newsocket;
309 	struct sockaddr_in address;
310 	qboolean _true = 0xFFFFFFFF;
311 
312 	//IPPROTO_TCP
313 	//
314 	if ( ( newsocket = socket( AF_INET, SOCK_STREAM, 0 ) ) == -1 ) {
315 		WinPrint( "WINS_OpenReliableSocket: %s\n", WINS_ErrorMessage( WSAGetLastError() ) );
316 		return -1;
317 	} //end if
318 
319 	memset( (char *) &address, 0, sizeof( address ) );
320 	address.sin_family = AF_INET;
321 	address.sin_addr.s_addr = htonl( INADDR_ANY );
322 	address.sin_port = htons( (u_short)port );
323 	if ( bind( newsocket, (void *)&address, sizeof( address ) ) == -1 ) {
324 		WinPrint( "WINS_OpenReliableSocket: %s\n", WINS_ErrorMessage( WSAGetLastError() ) );
325 		closesocket( newsocket );
326 		return -1;
327 	} //end if
328 
329 	//
330 	if ( setsockopt( newsocket, IPPROTO_TCP, TCP_NODELAY, (void *) &_true, sizeof( int ) ) == -1 ) {
331 		WinPrint( "WINS_OpenReliableSocket: %s\n", WINS_ErrorMessage( WSAGetLastError() ) );
332 		WinPrint( "setsockopt error\n" );
333 	} //end if
334 
335 	return newsocket;
336 } //end of the function WINS_OpenReliableSocket
337 //===========================================================================
338 //
339 // Parameter:				-
340 // Returns:					-
341 // Changes Globals:		-
342 //===========================================================================
WINS_Listen(int socket)343 int WINS_Listen( int socket ){
344 	u_long _true = 1;
345 
346 	if ( ioctlsocket( socket, FIONBIO, &_true ) == -1 ) {
347 		WinPrint( "WINS_Listen: %s\n", WINS_ErrorMessage( WSAGetLastError() ) );
348 		return -1;
349 	} //end if
350 	if ( listen( socket, SOMAXCONN ) == SOCKET_ERROR ) {
351 		WinPrint( "WINS_Listen: %s\n", WINS_ErrorMessage( WSAGetLastError() ) );
352 		return -1;
353 	} //end if
354 	return 0;
355 } //end of the function WINS_Listen
356 //===========================================================================
357 //
358 // Parameter:				-
359 // Returns:					-
360 // Changes Globals:		-
361 //===========================================================================
WINS_Accept(int socket,struct sockaddr_s * addr)362 int WINS_Accept( int socket, struct sockaddr_s *addr ){
363 	socklen_t addrlen = sizeof( struct sockaddr_s );
364 	int newsocket;
365 	qboolean _true = 1;
366 
367 	newsocket = accept( socket, (struct sockaddr *)addr, &addrlen );
368 	if ( newsocket == INVALID_SOCKET ) {
369 		if ( errno == EAGAIN ) {
370 			return -1;
371 		}
372 		WinPrint( "WINS_Accept: %s\n", WINS_ErrorMessage( WSAGetLastError() ) );
373 		return -1;
374 	} //end if
375 	  //
376 	if ( setsockopt( newsocket, IPPROTO_TCP, TCP_NODELAY, (void *) &_true, sizeof( int ) ) == SOCKET_ERROR ) {
377 		WinPrint( "WINS_Accept: %s\n", WINS_ErrorMessage( WSAGetLastError() ) );
378 		WinPrint( "setsockopt error\n" );
379 	} //end if
380 	return newsocket;
381 } //end of the function WINS_Accept
382 //===========================================================================
383 //
384 // Parameter:				-
385 // Returns:					-
386 // Changes Globals:		-
387 //===========================================================================
WINS_CloseSocket(int socket)388 int WINS_CloseSocket( int socket ){
389 	/*
390 	   if (socket == net_broadcastsocket)
391 	    net_broadcastsocket = 0;
392 	 */
393 //	shutdown(socket, SD_SEND);
394 
395 	if ( closesocket( socket ) == SOCKET_ERROR ) {
396 		WinPrint( "WINS_CloseSocket: %s\n", WINS_ErrorMessage( WSAGetLastError() ) );
397 		return SOCKET_ERROR;
398 	} //end if
399 	return 0;
400 } //end of the function WINS_CloseSocket
401 //===========================================================================
402 // this lets you type only as much of the net address as required, using
403 // the local network components to fill in the rest
404 //
405 // Parameter:				-
406 // Returns:					-
407 // Changes Globals:		-
408 //===========================================================================
PartialIPAddress(char * in,struct sockaddr_s * hostaddr)409 static int PartialIPAddress( char *in, struct sockaddr_s *hostaddr ){
410 	char buff[256];
411 	char *b;
412 	int addr;
413 	int num;
414 	int mask;
415 
416 	buff[0] = '.';
417 	b = buff;
418 	strcpy( buff + 1, in );
419 	if ( buff[1] == '.' ) {
420 		b++;
421 	}
422 
423 	addr = 0;
424 	mask = -1;
425 	while ( *b == '.' )
426 	{
427 		num = 0;
428 		if ( *++b < '0' || *b > '9' ) {
429 			return -1;
430 		}
431 		while ( !( *b < '0' || *b > '9' ) )
432 			num = num * 10 + *( b++ ) - '0';
433 		mask <<= 8;
434 		addr = ( addr << 8 ) + num;
435 	}
436 
437 	hostaddr->sa_family = AF_INET;
438 	( (struct sockaddr_in *)hostaddr )->sin_port = htons( (u_short)net_hostport );
439 	( (struct sockaddr_in *)hostaddr )->sin_addr.s_addr = ( myAddr & htonl( mask ) ) | htonl( addr );
440 
441 	return 0;
442 } //end of the function PartialIPAddress
443 //===========================================================================
444 //
445 // Parameter:				-
446 // Returns:					-
447 // Changes Globals:		-
448 //===========================================================================
WINS_Connect(int socket,struct sockaddr_s * addr)449 int WINS_Connect( int socket, struct sockaddr_s *addr ){
450 	int ret;
451 	u_long _true2 = 0xFFFFFFFF;
452 
453 	ret = connect( socket, (struct sockaddr *)addr, sizeof( struct sockaddr_s ) );
454 	if ( ret == SOCKET_ERROR ) {
455 		WinPrint( "WINS_Connect: %s\n", WINS_ErrorMessage( WSAGetLastError() ) );
456 		return -1;
457 	} //end if
458 	if ( ioctlsocket( socket, FIONBIO, &_true2 ) == -1 ) {
459 		WinPrint( "WINS_Connect: %s\n", WINS_ErrorMessage( WSAGetLastError() ) );
460 		return -1;
461 	} //end if
462 	return 0;
463 } //end of the function WINS_Connect
464 //===========================================================================
465 //
466 // Parameter:				-
467 // Returns:					-
468 // Changes Globals:		-
469 //===========================================================================
WINS_CheckNewConnections(void)470 int WINS_CheckNewConnections( void ){
471 	char buf[4];
472 
473 	if ( net_acceptsocket == -1 ) {
474 		return -1;
475 	}
476 
477 	if ( recvfrom( net_acceptsocket, buf, 4, MSG_PEEK, NULL, NULL ) > 0 ) {
478 		return net_acceptsocket;
479 	}
480 	return -1;
481 } //end of the function WINS_CheckNewConnections
482 //===========================================================================
483 // returns the number of bytes read
484 // 0 if no bytes available
485 // -1 on failure
486 //
487 // Parameter:				-
488 // Returns:					-
489 // Changes Globals:		-
490 //===========================================================================
WINS_Read(int socket,byte * buf,int len,struct sockaddr_s * addr)491 int WINS_Read( int socket, byte *buf, int len, struct sockaddr_s *addr ){
492 	socklen_t addrlen = sizeof( struct sockaddr_s );
493 	int ret;
494 
495 	if ( addr ) {
496 		ret = recvfrom( socket, buf, len, 0, (struct sockaddr *)addr, &addrlen );
497 		if ( ret == -1 ) {
498 //			errno = WSAGetLastError();
499 
500 			if ( errno == EAGAIN || errno == ENOTCONN ) {
501 				return 0;
502 			}
503 		} //end if
504 	} //end if
505 	else
506 	{
507 		ret = recv( socket, buf, len, 0 );
508 		// if there's no data on the socket ret == -1 and errno == EAGAIN
509 		// MSDN states that if ret == 0 the socket has been closed
510 		// man recv doesn't say anything
511 		if ( ret == 0 ) {
512 			return -1;
513 		}
514 		if ( ret == SOCKET_ERROR ) {
515 //			errno = WSAGetLastError();
516 
517 			if ( errno == EAGAIN || errno == ENOTCONN ) {
518 				return 0;
519 			}
520 		} //end if
521 	} //end else
522 	if ( ret == SOCKET_ERROR ) {
523 		WinPrint( "WINS_Read: %s\n", WINS_ErrorMessage( WSAGetLastError() ) );
524 	} //end if
525 	return ret;
526 } //end of the function WINS_Read
527 //===========================================================================
528 //
529 // Parameter:				-
530 // Returns:					-
531 // Changes Globals:		-
532 //===========================================================================
WINS_MakeSocketBroadcastCapable(int socket)533 int WINS_MakeSocketBroadcastCapable( int socket ){
534 	int i = 1;
535 
536 	// make this socket broadcast capable
537 	if ( setsockopt( socket, SOL_SOCKET, SO_BROADCAST, (char *)&i, sizeof( i ) ) < 0 ) {
538 		return -1;
539 	}
540 	net_broadcastsocket = socket;
541 
542 	return 0;
543 } //end of the function WINS_MakeSocketBroadcastCapable
544 //===========================================================================
545 //
546 // Parameter:				-
547 // Returns:					-
548 // Changes Globals:		-
549 //===========================================================================
WINS_Broadcast(int socket,byte * buf,int len)550 int WINS_Broadcast( int socket, byte *buf, int len ){
551 	int ret;
552 
553 	if ( socket != net_broadcastsocket ) {
554 		if ( net_broadcastsocket != 0 ) {
555 			WinError( "Attempted to use multiple broadcasts sockets\n" );
556 		}
557 		ret = WINS_MakeSocketBroadcastCapable( socket );
558 		if ( ret == -1 ) {
559 			WinPrint( "Unable to make socket broadcast capable\n" );
560 			return ret;
561 		}
562 	}
563 
564 	return WINS_Write( socket, buf, len, &broadcastaddr );
565 } //end of the function WINS_Broadcast
566 //===========================================================================
567 // returns qtrue on success or qfalse on failure
568 //
569 // Parameter:				-
570 // Returns:					-
571 // Changes Globals:		-
572 //===========================================================================
WINS_Write(int socket,byte * buf,int len,struct sockaddr_s * addr)573 int WINS_Write( int socket, byte *buf, int len, struct sockaddr_s *addr ){
574 	int ret, written;
575 	ret = 0;
576 
577 	if ( addr ) {
578 		written = 0;
579 		while ( written < len )
580 		{
581 			ret = sendto( socket, &buf[written], len - written, 0, (struct sockaddr *)addr, sizeof( struct sockaddr_s ) );
582 			if ( ret == SOCKET_ERROR ) {
583 				if ( WSAGetLastError() != EAGAIN ) {
584 					return qfalse;
585 				}
586 				//++timo FIXME: what is this used for?
587 //				Sleep(1000);
588 			} //end if
589 			else
590 			{
591 				written += ret;
592 			}
593 		}
594 	} //end if
595 	else
596 	{
597 		written = 0;
598 		while ( written < len )
599 		{
600 			ret = send( socket, buf, len, 0 );
601 			if ( ret == SOCKET_ERROR ) {
602 				if ( WSAGetLastError() != EAGAIN ) {
603 					return qfalse;
604 				}
605 				//++timo FIXME: what is this used for?
606 //				Sleep(1000);
607 			} //end if
608 			else
609 			{
610 				written += ret;
611 			}
612 		}
613 	} //end else
614 	if ( ret == SOCKET_ERROR ) {
615 		WinPrint( "WINS_Write: %s\n", WINS_ErrorMessage( WSAGetLastError() ) );
616 	} //end if
617 	return ( ret == len );
618 } //end of the function WINS_Write
619 //===========================================================================
620 //
621 // Parameter:				-
622 // Returns:					-
623 // Changes Globals:		-
624 //===========================================================================
WINS_AddrToString(struct sockaddr_s * addr)625 char *WINS_AddrToString( struct sockaddr_s *addr ){
626 	static char buffer[22];
627 	int haddr;
628 
629 	haddr = ntohl( ( (struct sockaddr_in *)addr )->sin_addr.s_addr );
630 	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 ) );
631 	return buffer;
632 } //end of the function WINS_AddrToString
633 //===========================================================================
634 //
635 // Parameter:				-
636 // Returns:					-
637 // Changes Globals:		-
638 //===========================================================================
WINS_StringToAddr(char * string,struct sockaddr_s * addr)639 int WINS_StringToAddr( char *string, struct sockaddr_s *addr ){
640 	int ha1, ha2, ha3, ha4, hp;
641 	int ipaddr;
642 
643 	sscanf( string, "%d.%d.%d.%d:%d", &ha1, &ha2, &ha3, &ha4, &hp );
644 	ipaddr = ( ha1 << 24 ) | ( ha2 << 16 ) | ( ha3 << 8 ) | ha4;
645 
646 	addr->sa_family = AF_INET;
647 	( (struct sockaddr_in *)addr )->sin_addr.s_addr = htonl( ipaddr );
648 	( (struct sockaddr_in *)addr )->sin_port = htons( (u_short)hp );
649 	return 0;
650 } //end of the function WINS_StringToAddr
651 //===========================================================================
652 //
653 // Parameter:				-
654 // Returns:					-
655 // Changes Globals:		-
656 //===========================================================================
WINS_GetSocketAddr(int socket,struct sockaddr_s * addr)657 int WINS_GetSocketAddr( int socket, struct sockaddr_s *addr ){
658 	socklen_t addrlen = sizeof( struct sockaddr_s );
659 	unsigned int a;
660 
661 	memset( addr, 0, sizeof( struct sockaddr_s ) );
662 	getsockname( socket, (struct sockaddr *)addr, &addrlen );
663 	a = ( (struct sockaddr_in *)addr )->sin_addr.s_addr;
664 	if ( a == 0 || a == inet_addr( "127.0.0.1" ) ) {
665 		( (struct sockaddr_in *)addr )->sin_addr.s_addr = myAddr;
666 	}
667 
668 	return 0;
669 } //end of the function WINS_GetSocketAddr
670 //===========================================================================
671 //
672 // Parameter:				-
673 // Returns:					-
674 // Changes Globals:		-
675 //===========================================================================
WINS_GetNameFromAddr(struct sockaddr_s * addr,char * name)676 int WINS_GetNameFromAddr( struct sockaddr_s *addr, char *name ){
677 	struct hostent *hostentry;
678 
679 	hostentry = gethostbyaddr( (char *)&( (struct sockaddr_in *)addr )->sin_addr, sizeof( struct in_addr ), AF_INET );
680 	if ( hostentry ) {
681 		strncpy( name, (char *)hostentry->h_name, NET_NAMELEN - 1 );
682 		return 0;
683 	}
684 
685 	strcpy( name, WINS_AddrToString( addr ) );
686 	return 0;
687 } //end of the function WINS_GetNameFromAddr
688 //===========================================================================
689 //
690 // Parameter:				-
691 // Returns:					-
692 // Changes Globals:		-
693 //===========================================================================
WINS_GetAddrFromName(char * name,struct sockaddr_s * addr)694 int WINS_GetAddrFromName( char *name, struct sockaddr_s *addr ){
695 	struct hostent *hostentry;
696 
697 	if ( name[0] >= '0' && name[0] <= '9' ) {
698 		return PartialIPAddress( name, addr );
699 	}
700 
701 	hostentry = gethostbyname( name );
702 	if ( !hostentry ) {
703 		return -1;
704 	}
705 
706 	addr->sa_family = AF_INET;
707 	( (struct sockaddr_in *)addr )->sin_port = htons( (u_short)net_hostport );
708 	( (struct sockaddr_in *)addr )->sin_addr.s_addr = *(int *)hostentry->h_addr_list[0];
709 
710 	return 0;
711 } //end of the function WINS_GetAddrFromName
712 //===========================================================================
713 //
714 // Parameter:				-
715 // Returns:					-
716 // Changes Globals:		-
717 //===========================================================================
WINS_AddrCompare(struct sockaddr_s * addr1,struct sockaddr_s * addr2)718 int WINS_AddrCompare( struct sockaddr_s *addr1, struct sockaddr_s *addr2 ){
719 	if ( addr1->sa_family != addr2->sa_family ) {
720 		return -1;
721 	}
722 
723 	if ( ( (struct sockaddr_in *)addr1 )->sin_addr.s_addr != ( (struct sockaddr_in *)addr2 )->sin_addr.s_addr ) {
724 		return -1;
725 	}
726 
727 	if ( ( (struct sockaddr_in *)addr1 )->sin_port != ( (struct sockaddr_in *)addr2 )->sin_port ) {
728 		return 1;
729 	}
730 
731 	return 0;
732 } //end of the function WINS_AddrCompare
733 //===========================================================================
734 //
735 // Parameter:				-
736 // Returns:					-
737 // Changes Globals:		-
738 //===========================================================================
WINS_GetSocketPort(struct sockaddr_s * addr)739 int WINS_GetSocketPort( struct sockaddr_s *addr ){
740 	return ntohs( ( (struct sockaddr_in *)addr )->sin_port );
741 } //end of the function WINS_GetSocketPort
742 //===========================================================================
743 //
744 // Parameter:				-
745 // Returns:					-
746 // Changes Globals:		-
747 //===========================================================================
WINS_SetSocketPort(struct sockaddr_s * addr,int port)748 int WINS_SetSocketPort( struct sockaddr_s *addr, int port ){
749 	( (struct sockaddr_in *)addr )->sin_port = htons( (u_short)port );
750 	return 0;
751 } //end of the function WINS_SetSocketPort
752