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