File: win32\net_wins.c
1 /*
2 Copyright (C) 1997-2001 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_wins.c
21
22 #include "winsock.h"
23 #include "wsipx.h"
24 #include "../qcommon/qcommon.h"
25
26 #define MAX_LOOPBACK 4
27
28 typedef struct
29 {
30 byte data[MAX_MSGLEN];
31 int datalen;
32 } loopmsg_t;
33
34 typedef struct
35 {
36 loopmsg_t msgs[MAX_LOOPBACK];
37 int get, send;
38 } loopback_t;
39
40
41 cvar_t *net_shownet;
42 static cvar_t *noudp;
43 static cvar_t *noipx;
44
45 loopback_t loopbacks[2];
46 int ip_sockets[2];
47 int ipx_sockets[2];
48
49 char *NET_ErrorString (void);
50
51 //=============================================================================
52
53 void NetadrToSockadr (netadr_t *a, struct sockaddr *s)
54 {
55 memset (s, 0, sizeof(*s));
56
57 if (a->type == NA_BROADCAST)
58 {
59 ((struct sockaddr_in *)s)->sin_family = AF_INET;
60 ((struct sockaddr_in *)s)->sin_port = a->port;
61 ((struct sockaddr_in *)s)->sin_addr.s_addr = INADDR_BROADCAST;
62 }
63 else if (a->type == NA_IP)
64 {
65 ((struct sockaddr_in *)s)->sin_family = AF_INET;
66 ((struct sockaddr_in *)s)->sin_addr.s_addr = *(int *)&a->ip;
67 ((struct sockaddr_in *)s)->sin_port = a->port;
68 }
69 else if (a->type == NA_IPX)
70 {
71 ((struct sockaddr_ipx *)s)->sa_family = AF_IPX;
72 memcpy(((struct sockaddr_ipx *)s)->sa_netnum, &a->ipx[0], 4);
73 memcpy(((struct sockaddr_ipx *)s)->sa_nodenum, &a->ipx[4], 6);
74 ((struct sockaddr_ipx *)s)->sa_socket = a->port;
75 }
76 else if (a->type == NA_BROADCAST_IPX)
77 {
78 ((struct sockaddr_ipx *)s)->sa_family = AF_IPX;
79 memset(((struct sockaddr_ipx *)s)->sa_netnum, 0, 4);
80 memset(((struct sockaddr_ipx *)s)->sa_nodenum, 0xff, 6);
81 ((struct sockaddr_ipx *)s)->sa_socket = a->port;
82 }
83 }
84
85 void SockadrToNetadr (struct sockaddr *s, netadr_t *a)
86 {
87 if (s->sa_family == AF_INET)
88 {
89 a->type = NA_IP;
90 *(int *)&a->ip = ((struct sockaddr_in *)s)->sin_addr.s_addr;
91 a->port = ((struct sockaddr_in *)s)->sin_port;
92 }
93 else if (s->sa_family == AF_IPX)
94 {
95 a->type = NA_IPX;
96 memcpy(&a->ipx[0], ((struct sockaddr_ipx *)s)->sa_netnum, 4);
97 memcpy(&a->ipx[4], ((struct sockaddr_ipx *)s)->sa_nodenum, 6);
98 a->port = ((struct sockaddr_ipx *)s)->sa_socket;
99 }
100 }
101
102
103 qboolean NET_CompareAdr (netadr_t a, netadr_t b)
104 {
105 if (a.type != b.type)
106 return false;
107
108 if (a.type == NA_LOOPBACK)
109 return TRUE;
110
111 if (a.type == NA_IP)
112 {
113 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)
114 return true;
115 return false;
116 }
117
118 if (a.type == NA_IPX)
119 {
120 if ((memcmp(a.ipx, b.ipx, 10) == 0) && a.port == b.port)
121 return true;
122 return false;
123 }
124 }
125
126 /*
127 ===================
128 NET_CompareBaseAdr
129
130 Compares without the port
131 ===================
132 */
133 qboolean NET_CompareBaseAdr (netadr_t a, netadr_t b)
134 {
135 if (a.type != b.type)
136 return false;
137
138 if (a.type == NA_LOOPBACK)
139 return TRUE;
140
141 if (a.type == NA_IP)
142 {
143 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])
144 return true;
145 return false;
146 }
147
148 if (a.type == NA_IPX)
149 {
150 if ((memcmp(a.ipx, b.ipx, 10) == 0))
151 return true;
152 return false;
153 }
154 }
155
156 char *NET_AdrToString (netadr_t a)
157 {
158 static char s[64];
159
160 if (a.type == NA_LOOPBACK)
161 Com_sprintf (s, sizeof(s), "loopback");
162 else if (a.type == NA_IP)
163 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));
164 else
165 Com_sprintf (s, sizeof(s), "%02x%02x%02x%02x:%02x%02x%02x%02x%02x%02x:%i", a.ipx[0], a.ipx[1], a.ipx[2], a.ipx[3], a.ipx[4], a.ipx[5], a.ipx[6], a.ipx[7], a.ipx[8], a.ipx[9], ntohs(a.port));
166
167 return s;
168 }
169
170
171 /*
172 =============
173 NET_StringToAdr
174
175 localhost
176 idnewt
177 idnewt:28000
178 192.246.40.70
179 192.246.40.70:28000
180 =============
181 */
182 #define DO(src,dest) \
183 copy[0] = s[src]; \
184 copy[1] = s[src + 1]; \
185 sscanf (copy, "%x", &val); \
186 ((struct sockaddr_ipx *)sadr)->dest = val
187
188 qboolean NET_StringToSockaddr (char *s, struct sockaddr *sadr)
189 {
190 struct hostent *h;
191 char *colon;
192 int val;
193 char copy[128];
194
195 memset (sadr, 0, sizeof(*sadr));
196
197 if ((strlen(s) >= 23) && (s[8] == ':') && (s[21] == ':')) // check for an IPX address
198 {
199 ((struct sockaddr_ipx *)sadr)->sa_family = AF_IPX;
200 copy[2] = 0;
201 DO(0, sa_netnum[0]);
202 DO(2, sa_netnum[1]);
203 DO(4, sa_netnum[2]);
204 DO(6, sa_netnum[3]);
205 DO(9, sa_nodenum[0]);
206 DO(11, sa_nodenum[1]);
207 DO(13, sa_nodenum[2]);
208 DO(15, sa_nodenum[3]);
209 DO(17, sa_nodenum[4]);
210 DO(19, sa_nodenum[5]);
211 sscanf (&s[22], "%u", &val);
212 ((struct sockaddr_ipx *)sadr)->sa_socket = htons((unsigned short)val);
213 }
214 else
215 {
216 ((struct sockaddr_in *)sadr)->sin_family = AF_INET;
217
218 ((struct sockaddr_in *)sadr)->sin_port = 0;
219
220 strcpy (copy, s);
221 // strip off a trailing :port if present
222 for (colon = copy ; *colon ; colon++)
223 if (*colon == ':')
224 {
225 *colon = 0;
226 ((struct sockaddr_in *)sadr)->sin_port = htons((short)atoi(colon+1));
227 }
228
229 if (copy[0] >= '0' && copy[0] <= '9')
230 {
231 *(int *)&((struct sockaddr_in *)sadr)->sin_addr = inet_addr(copy);
232 }
233 else
234 {
235 if (! (h = gethostbyname(copy)) )
236 return 0;
237 *(int *)&((struct sockaddr_in *)sadr)->sin_addr = *(int *)h->h_addr_list[0];
238 }
239 }
240
241 return true;
242 }
243
244 #undef DO
245
246 /*
247 =============
248 NET_StringToAdr
249
250 localhost
251 idnewt
252 idnewt:28000
253 192.246.40.70
254 192.246.40.70:28000
255 =============
256 */
257 qboolean NET_StringToAdr (char *s, netadr_t *a)
258 {
259 struct sockaddr sadr;
260
261 if (!strcmp (s, "localhost"))
262 {
263 memset (a, 0, sizeof(*a));
264 a->type = NA_LOOPBACK;
265 return true;
266 }
267
268 if (!NET_StringToSockaddr (s, &sadr))
269 return false;
270
271 SockadrToNetadr (&sadr, a);
272
273 return true;
274 }
275
276
277 qboolean NET_IsLocalAddress (netadr_t adr)
278 {
279 return adr.type == NA_LOOPBACK;
280 }
281
282 /*
283 =============================================================================
284
285 LOOPBACK BUFFERS FOR LOCAL PLAYER
286
287 =============================================================================
288 */
289
290 qboolean NET_GetLoopPacket (netsrc_t sock, netadr_t *net_from, sizebuf_t *net_message)
291 {
292 int i;
293 loopback_t *loop;
294
295 loop = &loopbacks[sock];
296
297 if (loop->send - loop->get > MAX_LOOPBACK)
298 loop->get = loop->send - MAX_LOOPBACK;
299
300 if (loop->get >= loop->send)
301 return false;
302
303 i = loop->get & (MAX_LOOPBACK-1);
304 loop->get++;
305
306 memcpy (net_message->data, loop->msgs[i].data, loop->msgs[i].datalen);
307 net_message->cursize = loop->msgs[i].datalen;
308 memset (net_from, 0, sizeof(*net_from));
309 net_from->type = NA_LOOPBACK;
310 return true;
311
312 }
313
314
315 void NET_SendLoopPacket (netsrc_t sock, int length, void *data, netadr_t to)
316 {
317 int i;
318 loopback_t *loop;
319
320 loop = &loopbacks[sock^1];
321
322 i = loop->send & (MAX_LOOPBACK-1);
323 loop->send++;
324
325 memcpy (loop->msgs[i].data, data, length);
326 loop->msgs[i].datalen = length;
327 }
328
329 //=============================================================================
330
331 qboolean NET_GetPacket (netsrc_t sock, netadr_t *net_from, sizebuf_t *net_message)
332 {
333 int ret;
334 struct sockaddr from;
335 int fromlen;
336 int net_socket;
337 int protocol;
338 int err;
339
340 if (NET_GetLoopPacket (sock, net_from, net_message))
341 return true;
342
343 for (protocol = 0 ; protocol < 2 ; protocol++)
344 {
345 if (protocol == 0)
346 net_socket = ip_sockets[sock];
347 else
348 net_socket = ipx_sockets[sock];
349
350 if (!net_socket)
351 continue;
352
353 fromlen = sizeof(from);
354 ret = recvfrom (net_socket, net_message->data, net_message->maxsize
355 , 0, (struct sockaddr *)&from, &fromlen);
356
357 SockadrToNetadr (&from, net_from);
358
359 if (ret == -1)
360 {
361 err = WSAGetLastError();
362
363 if (err == WSAEWOULDBLOCK)
364 continue;
365 if (err == WSAEMSGSIZE) {
366 Com_Printf ("Warning: Oversize packet from %s\n",
367 NET_AdrToString(*net_from));
368 continue;
369 }
370
371 if (dedicated->value) // let dedicated servers continue after errors
372 Com_Printf ("NET_GetPacket: %s from %s\n", NET_ErrorString(),
373 NET_AdrToString(*net_from));
374 else
375 Com_Error (ERR_DROP, "NET_GetPacket: %s from %s",
376 NET_ErrorString(), NET_AdrToString(*net_from));
377 continue;
378 }
379
380 if (ret == net_message->maxsize)
381 {
382 Com_Printf ("Oversize packet from %s\n", NET_AdrToString (*net_from));
383 continue;
384 }
385
386 net_message->cursize = ret;
387 return true;
388 }
389
390 return false;
391 }
392
393 //=============================================================================
394
395 void NET_SendPacket (netsrc_t sock, int length, void *data, netadr_t to)
396 {
397 int ret;
398 struct sockaddr addr;
399 int net_socket;
400
401 if ( to.type == NA_LOOPBACK )
402 {
403 NET_SendLoopPacket (sock, length, data, to);
404 return;
405 }
406
407 if (to.type == NA_BROADCAST)
408 {
409 net_socket = ip_sockets[sock];
410 if (!net_socket)
411 return;
412 }
413 else if (to.type == NA_IP)
414 {
415 net_socket = ip_sockets[sock];
416 if (!net_socket)
417 return;
418 }
419 else if (to.type == NA_IPX)
420 {
421 net_socket = ipx_sockets[sock];
422 if (!net_socket)
423 return;
424 }
425 else if (to.type == NA_BROADCAST_IPX)
426 {
427 net_socket = ipx_sockets[sock];
428 if (!net_socket)
429 return;
430 }
431 else
432 Com_Error (ERR_FATAL, "NET_SendPacket: bad address type");
433
434 NetadrToSockadr (&to, &addr);
435
436 ret = sendto (net_socket, data, length, 0, &addr, sizeof(addr) );
437 if (ret == -1)
438 {
439 int err = WSAGetLastError();
440
441 // wouldblock is silent
442 if (err == WSAEWOULDBLOCK)
443 return;
444
445 // some PPP links dont allow broadcasts
446 if ((err == WSAEADDRNOTAVAIL) && ((to.type == NA_BROADCAST) || (to.type == NA_BROADCAST_IPX)))
447 return;
448
449 if (dedicated->value) // let dedicated servers continue after errors
450 {
451 Com_Printf ("NET_SendPacket ERROR: %s to %s\n", NET_ErrorString(),
452 NET_AdrToString (to));
453 }
454 else
455 {
456 if (err == WSAEADDRNOTAVAIL)
457 {
458 Com_DPrintf ("NET_SendPacket Warning: %s : %s\n",
459 NET_ErrorString(), NET_AdrToString (to));
460 }
461 else
462 {
463 Com_Error (ERR_DROP, "NET_SendPacket ERROR: %s to %s\n",
464 NET_ErrorString(), NET_AdrToString (to));
465 }
466 }
467 }
468 }
469
470
471 //=============================================================================
472
473
474 /*
475 ====================
476 NET_Socket
477 ====================
478 */
479 int NET_IPSocket (char *net_interface, int port)
480 {
481 int newsocket;
482 struct sockaddr_in address;
483 qboolean _true = true;
484 int i = 1;
485 int err;
486
487 if ((newsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
488 {
489 err = WSAGetLastError();
490 if (err != WSAEAFNOSUPPORT)
491 Com_Printf ("WARNING: UDP_OpenSocket: socket: %s", NET_ErrorString());
492 return 0;
493 }
494
495 // make it non-blocking
496 if (ioctlsocket (newsocket, FIONBIO, &_true) == -1)
497 {
498 Com_Printf ("WARNING: UDP_OpenSocket: ioctl FIONBIO: %s\n", NET_ErrorString());
499 return 0;
500 }
501
502 // make it broadcast capable
503 if (setsockopt(newsocket, SOL_SOCKET, SO_BROADCAST, (char *)&i, sizeof(i)) == -1)
504 {
505 Com_Printf ("WARNING: UDP_OpenSocket: setsockopt SO_BROADCAST: %s\n", NET_ErrorString());
506 return 0;
507 }
508
509 if (!net_interface || !net_interface[0] || !stricmp(net_interface, "localhost"))
510 address.sin_addr.s_addr = INADDR_ANY;
511 else
512 NET_StringToSockaddr (net_interface, (struct sockaddr *)&address);
513
514 if (port == PORT_ANY)
515 address.sin_port = 0;
516 else
517 address.sin_port = htons((short)port);
518
519 address.sin_family = AF_INET;
520
521 if( bind (newsocket, (void *)&address, sizeof(address)) == -1)
522 {
523 Com_Printf ("WARNING: UDP_OpenSocket: bind: %s\n", NET_ErrorString());
524 closesocket (newsocket);
525 return 0;
526 }
527
528 return newsocket;
529 }
530
531
532 /*
533 ====================
534 NET_OpenIP
535 ====================
536 */
537 void NET_OpenIP (void)
538 {
539 cvar_t *ip;
540 int port;
541 int dedicated;
542
543 ip = Cvar_Get ("ip", "localhost", CVAR_NOSET);
544
545 dedicated = Cvar_VariableValue ("dedicated");
546
547 if (!ip_sockets[NS_SERVER])
548 {
549 port = Cvar_Get("ip_hostport", "0", CVAR_NOSET)->value;
550 if (!port)
551 {
552 port = Cvar_Get("hostport", "0", CVAR_NOSET)->value;
553 if (!port)
554 {
555 port = Cvar_Get("port", va("%i", PORT_SERVER), CVAR_NOSET)->value;
556 }
557 }
558 ip_sockets[NS_SERVER] = NET_IPSocket (ip->string, port);
559 if (!ip_sockets[NS_SERVER] && dedicated)
560 Com_Error (ERR_FATAL, "Couldn't allocate dedicated server IP port");
561 }
562
563
564 // dedicated servers don't need client ports
565 if (dedicated)
566 return;
567
568 if (!ip_sockets[NS_CLIENT])
569 {
570 port = Cvar_Get("ip_clientport", "0", CVAR_NOSET)->value;
571 if (!port)
572 {
573 port = Cvar_Get("clientport", va("%i", PORT_CLIENT), CVAR_NOSET)->value;
574 if (!port)
575 port = PORT_ANY;
576 }
577 ip_sockets[NS_CLIENT] = NET_IPSocket (ip->string, port);
578 if (!ip_sockets[NS_CLIENT])
579 ip_sockets[NS_CLIENT] = NET_IPSocket (ip->string, PORT_ANY);
580 }
581 }
582
583
584 /*
585 ====================
586 IPX_Socket
587 ====================
588 */
589 int NET_IPXSocket (int port)
590 {
591 int newsocket;
592 struct sockaddr_ipx address;
593 int _true = 1;
594 int err;
595
596 if ((newsocket = socket (PF_IPX, SOCK_DGRAM, NSPROTO_IPX)) == -1)
597 {
598 err = WSAGetLastError();
599 if (err != WSAEAFNOSUPPORT)
600 Com_Printf ("WARNING: IPX_Socket: socket: %s\n", NET_ErrorString());
601 return 0;
602 }
603
604 // make it non-blocking
605 if (ioctlsocket (newsocket, FIONBIO, &_true) == -1)
606 {
607 Com_Printf ("WARNING: IPX_Socket: ioctl FIONBIO: %s\n", NET_ErrorString());
608 return 0;
609 }
610
611 // make it broadcast capable
612 if (setsockopt(newsocket, SOL_SOCKET, SO_BROADCAST, (char *)&_true, sizeof(_true)) == -1)
613 {
614 Com_Printf ("WARNING: IPX_Socket: setsockopt SO_BROADCAST: %s\n", NET_ErrorString());
615 return 0;
616 }
617
618 address.sa_family = AF_IPX;
619 memset (address.sa_netnum, 0, 4);
620 memset (address.sa_nodenum, 0, 6);
621 if (port == PORT_ANY)
622 address.sa_socket = 0;
623 else
624 address.sa_socket = htons((short)port);
625
626 if( bind (newsocket, (void *)&address, sizeof(address)) == -1)
627 {
628 Com_Printf ("WARNING: IPX_Socket: bind: %s\n", NET_ErrorString());
629 closesocket (newsocket);
630 return 0;
631 }
632
633 return newsocket;
634 }
635
636
637 /*
638 ====================
639 NET_OpenIPX
640 ====================
641 */
642 void NET_OpenIPX (void)
643 {
644 int port;
645 int dedicated;
646
647 dedicated = Cvar_VariableValue ("dedicated");
648
649 if (!ipx_sockets[NS_SERVER])
650 {
651 port = Cvar_Get("ipx_hostport", "0", CVAR_NOSET)->value;
652 if (!port)
653 {
654 port = Cvar_Get("hostport", "0", CVAR_NOSET)->value;
655 if (!port)
656 {
657 port = Cvar_Get("port", va("%i", PORT_SERVER), CVAR_NOSET)->value;
658 }
659 }
660 ipx_sockets[NS_SERVER] = NET_IPXSocket (port);
661 }
662
663 // dedicated servers don't need client ports
664 if (dedicated)
665 return;
666
667 if (!ipx_sockets[NS_CLIENT])
668 {
669 port = Cvar_Get("ipx_clientport", "0", CVAR_NOSET)->value;
670 if (!port)
671 {
672 port = Cvar_Get("clientport", va("%i", PORT_CLIENT), CVAR_NOSET)->value;
673 if (!port)
674 port = PORT_ANY;
675 }
676 ipx_sockets[NS_CLIENT] = NET_IPXSocket (port);
677 if (!ipx_sockets[NS_CLIENT])
678 ipx_sockets[NS_CLIENT] = NET_IPXSocket (PORT_ANY);
679 }
680 }
681
682
683 /*
684 ====================
685 NET_Config
686
687 A single player game will only use the loopback code
688 ====================
689 */
690 void NET_Config (qboolean multiplayer)
691 {
692 int i;
693 static qboolean old_config;
694
695 if (old_config == multiplayer)
696 return;
697
698 old_config = multiplayer;
699
700 if (!multiplayer)
701 { // shut down any existing sockets
702 for (i=0 ; i<2 ; i++)
703 {
704 if (ip_sockets[i])
705 {
706 closesocket (ip_sockets[i]);
707 ip_sockets[i] = 0;
708 }
709 if (ipx_sockets[i])
710 {
711 closesocket (ipx_sockets[i]);
712 ipx_sockets[i] = 0;
713 }
714 }
715 }
716 else
717 { // open sockets
718 if (! noudp->value)
719 NET_OpenIP ();
720 if (! noipx->value)
721 NET_OpenIPX ();
722 }
723 }
724
725 // sleeps msec or until net socket is ready
726 void NET_Sleep(int msec)
727 {
728 struct timeval timeout;
729 fd_set fdset;
730 extern cvar_t *dedicated;
731 int i;
732
733 if (!dedicated || !dedicated->value)
734 return; // we're not a server, just run full speed
735
736 FD_ZERO(&fdset);
737 i = 0;
738 if (ip_sockets[NS_SERVER]) {
739 FD_SET(ip_sockets[NS_SERVER], &fdset); // network socket
740 i = ip_sockets[NS_SERVER];
741 }
742 if (ipx_sockets[NS_SERVER]) {
743 FD_SET(ipx_sockets[NS_SERVER], &fdset); // network socket
744 if (ipx_sockets[NS_SERVER] > i)
745 i = ipx_sockets[NS_SERVER];
746 }
747 timeout.tv_sec = msec/1000;
748 timeout.tv_usec = (msec%1000)*1000;
749 select(i+1, &fdset, NULL, NULL, &timeout);
750 }
751
752 //===================================================================
753
754
755 static WSADATA winsockdata;
756
757 /*
758 ====================
759 NET_Init
760 ====================
761 */
762 void NET_Init (void)
763 {
764 WORD wVersionRequested;
765 int r;
766
767 wVersionRequested = MAKEWORD(1, 1);
768
769 r = WSAStartup (MAKEWORD(1, 1), &winsockdata);
770
771 if (r)
772 Com_Error (ERR_FATAL,"Winsock initialization failed.");
773
774 Com_Printf("Winsock Initialized\n");
775
776 noudp = Cvar_Get ("noudp", "0", CVAR_NOSET);
777 noipx = Cvar_Get ("noipx", "0", CVAR_NOSET);
778
779 net_shownet = Cvar_Get ("net_shownet", "0", 0);
780 }
781
782
783 /*
784 ====================
785 NET_Shutdown
786 ====================
787 */
788 void NET_Shutdown (void)
789 {
790 NET_Config (false); // close sockets
791
792 WSACleanup ();
793 }
794
795
796 /*
797 ====================
798 NET_ErrorString
799 ====================
800 */
801 char *NET_ErrorString (void)
802 {
803 int code;
804
805 code = WSAGetLastError ();
806 switch (code)
807 {
808 case WSAEINTR: return "WSAEINTR";
809 case WSAEBADF: return "WSAEBADF";
810 case WSAEACCES: return "WSAEACCES";
811 case WSAEDISCON: return "WSAEDISCON";
812 case WSAEFAULT: return "WSAEFAULT";
813 case WSAEINVAL: return "WSAEINVAL";
814 case WSAEMFILE: return "WSAEMFILE";
815 case WSAEWOULDBLOCK: return "WSAEWOULDBLOCK";
816 case WSAEINPROGRESS: return "WSAEINPROGRESS";
817 case WSAEALREADY: return "WSAEALREADY";
818 case WSAENOTSOCK: return "WSAENOTSOCK";
819 case WSAEDESTADDRREQ: return "WSAEDESTADDRREQ";
820 case WSAEMSGSIZE: return "WSAEMSGSIZE";
821 case WSAEPROTOTYPE: return "WSAEPROTOTYPE";
822 case WSAENOPROTOOPT: return "WSAENOPROTOOPT";
823 case WSAEPROTONOSUPPORT: return "WSAEPROTONOSUPPORT";
824 case WSAESOCKTNOSUPPORT: return "WSAESOCKTNOSUPPORT";
825 case WSAEOPNOTSUPP: return "WSAEOPNOTSUPP";
826 case WSAEPFNOSUPPORT: return "WSAEPFNOSUPPORT";
827 case WSAEAFNOSUPPORT: return "WSAEAFNOSUPPORT";
828 case WSAEADDRINUSE: return "WSAEADDRINUSE";
829 case WSAEADDRNOTAVAIL: return "WSAEADDRNOTAVAIL";
830 case WSAENETDOWN: return "WSAENETDOWN";
831 case WSAENETUNREACH: return "WSAENETUNREACH";
832 case WSAENETRESET: return "WSAENETRESET";
833 case WSAECONNABORTED: return "WSWSAECONNABORTEDAEINTR";
834 case WSAECONNRESET: return "WSAECONNRESET";
835 case WSAENOBUFS: return "WSAENOBUFS";
836 case WSAEISCONN: return "WSAEISCONN";
837 case WSAENOTCONN: return "WSAENOTCONN";
838 case WSAESHUTDOWN: return "WSAESHUTDOWN";
839 case WSAETOOMANYREFS: return "WSAETOOMANYREFS";
840 case WSAETIMEDOUT: return "WSAETIMEDOUT";
841 case WSAECONNREFUSED: return "WSAECONNREFUSED";
842 case WSAELOOP: return "WSAELOOP";
843 case WSAENAMETOOLONG: return "WSAENAMETOOLONG";
844 case WSAEHOSTDOWN: return "WSAEHOSTDOWN";
845 case WSASYSNOTREADY: return "WSASYSNOTREADY";
846 case WSAVERNOTSUPPORTED: return "WSAVERNOTSUPPORTED";
847 case WSANOTINITIALISED: return "WSANOTINITIALISED";
848 case WSAHOST_NOT_FOUND: return "WSAHOST_NOT_FOUND";
849 case WSATRY_AGAIN: return "WSATRY_AGAIN";
850 case WSANO_RECOVERY: return "WSANO_RECOVERY";
851 case WSANO_DATA: return "WSANO_DATA";
852 default: return "NO ERROR";
853 }
854 }
855