Annotation of quake2/win32/net_wins.c, revision 1.1.1.3

1.1.1.3 ! root        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: */
1.1       root       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);
1.1.1.3 ! root      356: 
        !           357:                SockadrToNetadr (&from, net_from);
        !           358: 
1.1       root      359:                if (ret == -1)
                    360:                {
                    361:                        err = WSAGetLastError();
                    362: 
                    363:                        if (err == WSAEWOULDBLOCK)
                    364:                                continue;
1.1.1.3 ! root      365:                        if (err == WSAEMSGSIZE) {
        !           366:                                Com_Printf ("Warning:  Oversize packet from %s\n",
        !           367:                                                NET_AdrToString(*net_from));
        !           368:                                continue;
        !           369:                        }
        !           370: 
1.1       root      371:                        if (dedicated->value)   // let dedicated servers continue after errors
1.1.1.3 ! root      372:                                Com_Printf ("NET_GetPacket: %s from %s\n", NET_ErrorString(),
        !           373:                                                NET_AdrToString(*net_from));
1.1       root      374:                        else
1.1.1.3 ! root      375:                                Com_Error (ERR_DROP, "NET_GetPacket: %s from %s", 
        !           376:                                                NET_ErrorString(), NET_AdrToString(*net_from));
1.1       root      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:                {
1.1.1.3 ! root      451:                        Com_Printf ("NET_SendPacket ERROR: %s to %s\n", NET_ErrorString(),
        !           452:                                NET_AdrToString (to));
1.1       root      453:                }
                    454:                else
                    455:                {
                    456:                        if (err == WSAEADDRNOTAVAIL)
                    457:                        {
1.1.1.3 ! root      458:                                Com_DPrintf ("NET_SendPacket Warning: %s : %s\n", 
        !           459:                                                NET_ErrorString(), NET_AdrToString (to));
1.1       root      460:                        }
                    461:                        else
                    462:                        {
1.1.1.3 ! root      463:                                Com_Error (ERR_DROP, "NET_SendPacket ERROR: %s to %s\n", 
        !           464:                                                NET_ErrorString(), NET_AdrToString (to));
1.1       root      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: 
1.1.1.2   root      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: }
1.1       root      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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.