Annotation of quake1/net_mp.c, revision 1.1

1.1     ! root        1: // net_mpath.c
        !             2: 
        !             3: #include <dpmi.h>
        !             4: #include "quakedef.h"
        !             5: #include "mpdosock.h"
        !             6: 
        !             7: short flat_selector;
        !             8: 
        !             9: int WSAGetLastError(void);
        !            10: void sockets_flush(void);
        !            11: 
        !            12: extern cvar_t hostname;
        !            13: 
        !            14: #define        DEFAULTnet_hostport     26000
        !            15: 
        !            16: #define MAXHOSTNAMELEN         256
        !            17: 
        !            18: static int net_acceptsocket = -1;              // socket for fielding new connections
        !            19: static int net_controlsocket;
        !            20: static int net_hostport;                               // udp port number for acceptsocket
        !            21: static int net_broadcastsocket = 0;
        !            22: //static qboolean ifbcastinit = false;
        !            23: static struct qsockaddr broadcastaddr;
        !            24: 
        !            25: static unsigned long myAddr;
        !            26: 
        !            27: #include "net_mp.h"
        !            28: 
        !            29: 
        !            30: //=============================================================================
        !            31: 
        !            32: int MPATH_Init (void)
        !            33: {
        !            34:        int             i;
        !            35:        struct hostent *local;
        !            36:        char    buff[MAXHOSTNAMELEN];
        !            37:        struct qsockaddr addr;
        !            38:        char    *p;
        !            39: 
        !            40:        if (COM_CheckParm ("-mpath") == 0)
        !            41:                return -1;
        !            42: 
        !            43:        i = COM_CheckParm ("-udpport");
        !            44:        if (i == 0)
        !            45:                net_hostport = DEFAULTnet_hostport;
        !            46:        else if (i < com_argc-1)
        !            47:                net_hostport = Q_atoi (com_argv[i+1]);
        !            48:        else
        !            49:                Sys_Error ("MPATH_Init: you must specify a number after -udpport");
        !            50: 
        !            51:    flat_selector = __dpmi_allocate_ldt_descriptors(1);
        !            52:    if (flat_selector == -1) {
        !            53:       Con_Printf("MPATH_Init: Can't get flat selector\n");
        !            54:       return -1;
        !            55:    }
        !            56:    if (__dpmi_set_segment_base_address(flat_selector, 0) == -1) {
        !            57:       Con_Printf("MPATH_Init: Can't seg flat base!\n");
        !            58:       return -1;
        !            59:    }
        !            60:    if (__dpmi_set_segment_limit(flat_selector, 0xffffffff) == -1) {
        !            61:       Con_Printf("MPATH_Init: Can't set segment limit\n");
        !            62:       return -1;
        !            63:    }
        !            64:        // determine my name & address
        !            65:        gethostname(buff, MAXHOSTNAMELEN);
        !            66:        local = gethostbyname(buff);
        !            67:        myAddr = *(int *)local->h_addr_list[0];
        !            68: 
        !            69:        // if the quake hostname isn't set, set it to the machine name
        !            70:        if (Q_strcmp(hostname.string, "UNNAMED") == 0)
        !            71:        {
        !            72:                // see if it's a text IP address (well, close enough)
        !            73:                for (p = buff; *p; p++)
        !            74:                        if ((*p < '0' || *p > '9') && *p != '.')
        !            75:                                break;
        !            76: 
        !            77:                // if it is a real name, strip off the domain; we only want the host
        !            78:                if (*p)
        !            79:                {
        !            80:                        for (i = 0; i < 15; i++)
        !            81:                                if (buff[i] == '.')
        !            82:                                        break;
        !            83:                        buff[i] = 0;
        !            84:                }
        !            85:                Cvar_Set ("hostname", buff);
        !            86:        }
        !            87: 
        !            88:        if ((net_controlsocket = MPATH_OpenSocket (0)) == -1)
        !            89:                Sys_Error("MPATH_Init: Unable to open control socket\n");
        !            90: 
        !            91:        ((struct sockaddr_in *)&broadcastaddr)->sin_family = AF_INET;
        !            92:        ((struct sockaddr_in *)&broadcastaddr)->sin_addr.s_addr = INADDR_BROADCAST;
        !            93:        ((struct sockaddr_in *)&broadcastaddr)->sin_port = htons(net_hostport);
        !            94: 
        !            95:        MPATH_GetSocketAddr (net_controlsocket, &addr);
        !            96:        Q_strcpy(my_tcpip_address,  MPATH_AddrToString (&addr));
        !            97:        p = Q_strrchr (my_tcpip_address, ':');
        !            98:        if (p)
        !            99:                *p = 0;
        !           100: 
        !           101:        Con_Printf("MPath Initialized\n");
        !           102:        tcpipAvailable = true;
        !           103: 
        !           104:        return net_controlsocket;
        !           105: }
        !           106: 
        !           107: //=============================================================================
        !           108: 
        !           109: void MPATH_Shutdown (void)
        !           110: {
        !           111:        MPATH_Listen (false);
        !           112:        MPATH_CloseSocket (net_controlsocket);
        !           113: }
        !           114: 
        !           115: //=============================================================================
        !           116: 
        !           117: void MPATH_Listen (qboolean state)
        !           118: {
        !           119:        // enable listening
        !           120:        if (state)
        !           121:        {
        !           122:                if (net_acceptsocket != -1)
        !           123:                        return;
        !           124:                if ((net_acceptsocket = MPATH_OpenSocket (net_hostport)) == -1)
        !           125:                        Sys_Error ("MPATH_Listen: Unable to open accept socket\n");
        !           126:                return;
        !           127:        }
        !           128: 
        !           129:        // disable listening
        !           130:        if (net_acceptsocket == -1)
        !           131:                return;
        !           132:        MPATH_CloseSocket (net_acceptsocket);
        !           133:        net_acceptsocket = -1;
        !           134: }
        !           135: 
        !           136: //=============================================================================
        !           137: 
        !           138: int MPATH_OpenSocket (int port)
        !           139: {
        !           140:        int newsocket;
        !           141:        struct sockaddr_in address;
        !           142:        u_long _true = 1;
        !           143: 
        !           144:        if ((newsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
        !           145:                return -1;
        !           146: 
        !           147:        if (ioctlsocket (newsocket, FIONBIO, &_true) == -1)
        !           148:                goto ErrorReturn;
        !           149: 
        !           150:        address.sin_family = AF_INET;
        !           151:        address.sin_addr.s_addr = INADDR_ANY;
        !           152:        address.sin_port = htons(port);
        !           153:        if( bind (newsocket, (void *)&address, sizeof(address)) == -1)
        !           154:                goto ErrorReturn;
        !           155: 
        !           156:        return newsocket;
        !           157: 
        !           158: ErrorReturn:
        !           159:        closesocket (newsocket);
        !           160:        return -1;
        !           161: }
        !           162: 
        !           163: //=============================================================================
        !           164: 
        !           165: int MPATH_CloseSocket (int socket)
        !           166: {
        !           167:        if (socket == net_broadcastsocket)
        !           168:                net_broadcastsocket = 0;
        !           169:        return closesocket (socket);
        !           170: }
        !           171: 
        !           172: 
        !           173: //=============================================================================
        !           174: /*
        !           175: ============
        !           176: PartialIPAddress
        !           177: 
        !           178: this lets you type only as much of the net address as required, using
        !           179: the local network components to fill in the rest
        !           180: ============
        !           181: */
        !           182: static int PartialIPAddress (char *in, struct qsockaddr *hostaddr)
        !           183: {
        !           184:        char buff[256];
        !           185:        char *b;
        !           186:        int addr;
        !           187:        int num;
        !           188:        int mask;
        !           189:        
        !           190:        buff[0] = '.';
        !           191:        b = buff;
        !           192:        strcpy(buff+1, in);
        !           193:        if (buff[1] == '.') b++;
        !           194: 
        !           195:        addr = 0;
        !           196:        mask=-1;
        !           197:        while (*b == '.')
        !           198:        {
        !           199:                num = 0;
        !           200:                if (*++b < '0' || *b > '9') return -1;
        !           201:                while (!( *b < '0' || *b > '9'))
        !           202:                  num = num*10 + *(b++) - '0';
        !           203:                mask<<=8;
        !           204:                addr = (addr<<8) + num;
        !           205:        }
        !           206:        
        !           207:        hostaddr->sa_family = AF_INET;
        !           208:        ((struct sockaddr_in *)hostaddr)->sin_port = htons(net_hostport);       
        !           209:        ((struct sockaddr_in *)hostaddr)->sin_addr.s_addr = (myAddr & htonl(mask)) | htonl(addr);
        !           210:        
        !           211:        return 0;
        !           212: }
        !           213: //=============================================================================
        !           214: 
        !           215: int MPATH_Connect (int socket, struct qsockaddr *addr)
        !           216: {
        !           217:        return 0;
        !           218: }
        !           219: 
        !           220: //=============================================================================
        !           221: 
        !           222: int MPATH_CheckNewConnections (void)
        !           223: {
        !           224:        char buf[4];
        !           225: 
        !           226:        if (net_acceptsocket == -1)
        !           227:                return -1;
        !           228: 
        !           229:        if (recvfrom (net_acceptsocket, buf, 4, MSG_PEEK, NULL, NULL) > 0)
        !           230:                return net_acceptsocket;
        !           231:        return -1;
        !           232: }
        !           233: 
        !           234: //=============================================================================
        !           235: 
        !           236: int MPATH_Read (int socket, byte *buf, int len, struct qsockaddr *addr)
        !           237: {
        !           238:        int addrlen = sizeof (struct qsockaddr);
        !           239:        int ret;
        !           240: 
        !           241:        ret = recvfrom (socket, buf, len, 0, (struct sockaddr *)addr, &addrlen);
        !           242:        if (ret == -1)
        !           243:        {
        !           244:                int errno = WSAGetLastError();
        !           245: 
        !           246:                if (errno == WSAEWOULDBLOCK || errno == WSAECONNREFUSED)
        !           247:                        return 0;
        !           248: 
        !           249:        }
        !           250:        return ret;
        !           251: }
        !           252: 
        !           253: //=============================================================================
        !           254: 
        !           255: int MPATH_MakeSocketBroadcastCapable (int socket)
        !           256: {
        !           257:        int     i = 1;
        !           258: 
        !           259:        // make this socket broadcast capable
        !           260:        if (setsockopt(socket, SOL_SOCKET, SO_BROADCAST, (char *)&i, sizeof(i)) < 0)
        !           261:                return -1;
        !           262:        net_broadcastsocket = socket;
        !           263: 
        !           264:        return 0;
        !           265: }
        !           266: 
        !           267: //=============================================================================
        !           268: 
        !           269: int MPATH_Broadcast (int socket, byte *buf, int len)
        !           270: {
        !           271:        int ret;
        !           272: 
        !           273:        if (socket != net_broadcastsocket)
        !           274:        {
        !           275:                if (net_broadcastsocket != 0)
        !           276:                        Sys_Error("Attempted to use multiple broadcasts sockets\n");
        !           277:                ret = MPATH_MakeSocketBroadcastCapable (socket);
        !           278:                if (ret == -1)
        !           279:                {
        !           280:                        Con_Printf("Unable to make socket broadcast capable\n");
        !           281:                        return ret;
        !           282:                }
        !           283:        }
        !           284: 
        !           285:        return MPATH_Write (socket, buf, len, &broadcastaddr);
        !           286: }
        !           287: 
        !           288: //=============================================================================
        !           289: 
        !           290: int MPATH_Write (int socket, byte *buf, int len, struct qsockaddr *addr)
        !           291: {
        !           292:        int ret;
        !           293: 
        !           294:        ret = sendto (socket, buf, len, 0, (struct sockaddr *)addr, sizeof(struct qsockaddr));
        !           295:        if (ret == -1)
        !           296:                if (WSAGetLastError() == WSAEWOULDBLOCK)
        !           297:                        return 0;
        !           298: 
        !           299:        sockets_flush();
        !           300: 
        !           301:        return ret;
        !           302: }
        !           303: 
        !           304: //=============================================================================
        !           305: 
        !           306: char *MPATH_AddrToString (struct qsockaddr *addr)
        !           307: {
        !           308:        static char buffer[22];
        !           309:        int haddr;
        !           310: 
        !           311:        haddr = ntohl(((struct sockaddr_in *)addr)->sin_addr.s_addr);
        !           312:        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));
        !           313:        return buffer;
        !           314: }
        !           315: 
        !           316: //=============================================================================
        !           317: 
        !           318: int MPATH_StringToAddr (char *string, struct qsockaddr *addr)
        !           319: {
        !           320:        int ha1, ha2, ha3, ha4, hp;
        !           321:        int ipaddr;
        !           322: 
        !           323:        sscanf(string, "%d.%d.%d.%d:%d", &ha1, &ha2, &ha3, &ha4, &hp);
        !           324:        ipaddr = (ha1 << 24) | (ha2 << 16) | (ha3 << 8) | ha4;
        !           325: 
        !           326:        addr->sa_family = AF_INET;
        !           327:        ((struct sockaddr_in *)addr)->sin_addr.s_addr = htonl(ipaddr);
        !           328:        ((struct sockaddr_in *)addr)->sin_port = htons(hp);
        !           329:        return 0;
        !           330: }
        !           331: 
        !           332: //=============================================================================
        !           333: 
        !           334: int MPATH_GetSocketAddr (int socket, struct qsockaddr *addr)
        !           335: {
        !           336:        int addrlen = sizeof(struct qsockaddr);
        !           337:        unsigned int a;
        !           338: 
        !           339:        Q_memset(addr, 0, sizeof(struct qsockaddr));
        !           340:        getsockname(socket, (struct sockaddr *)addr, &addrlen);
        !           341:        a = ((struct sockaddr_in *)addr)->sin_addr.s_addr;
        !           342:        if (a == 0 || a == inet_addr("127.0.0.1"))
        !           343:                ((struct sockaddr_in *)addr)->sin_addr.s_addr = myAddr;
        !           344: 
        !           345:        return 0;
        !           346: }
        !           347: 
        !           348: //=============================================================================
        !           349: 
        !           350: int MPATH_GetNameFromAddr (struct qsockaddr *addr, char *name)
        !           351: {
        !           352:        struct hostent *hostentry;
        !           353: 
        !           354:        hostentry = gethostbyaddr ((char *)&((struct sockaddr_in *)addr)->sin_addr, sizeof(struct in_addr), AF_INET);
        !           355:        if (hostentry)
        !           356:        {
        !           357:                Q_strncpy (name, (char *)hostentry->h_name, NET_NAMELEN - 1);
        !           358:                return 0;
        !           359:        }
        !           360: 
        !           361:        Q_strcpy (name, MPATH_AddrToString (addr));
        !           362:        return 0;
        !           363: }
        !           364: 
        !           365: //=============================================================================
        !           366: 
        !           367: int MPATH_GetAddrFromName(char *name, struct qsockaddr *addr)
        !           368: {
        !           369:        struct hostent *hostentry;
        !           370: 
        !           371:        if (name[0] >= '0' && name[0] <= '9')
        !           372:                return PartialIPAddress (name, addr);
        !           373:        
        !           374:        hostentry = gethostbyname (name);
        !           375:        if (!hostentry)
        !           376:                return -1;
        !           377: 
        !           378:        addr->sa_family = AF_INET;
        !           379:        ((struct sockaddr_in *)addr)->sin_port = htons(net_hostport);   
        !           380:        ((struct sockaddr_in *)addr)->sin_addr.s_addr = *(int *)hostentry->h_addr_list[0];
        !           381: 
        !           382:        return 0;
        !           383: }
        !           384: 
        !           385: //=============================================================================
        !           386: 
        !           387: int MPATH_AddrCompare (struct qsockaddr *addr1, struct qsockaddr *addr2)
        !           388: {
        !           389:        if (addr1->sa_family != addr2->sa_family)
        !           390:                return -1;
        !           391: 
        !           392:        if (((struct sockaddr_in *)addr1)->sin_addr.s_addr != ((struct sockaddr_in *)addr2)->sin_addr.s_addr)
        !           393:                return -1;
        !           394: 
        !           395:        if (((struct sockaddr_in *)addr1)->sin_port != ((struct sockaddr_in *)addr2)->sin_port)
        !           396:                return 1;
        !           397: 
        !           398:        return 0;
        !           399: }
        !           400: 
        !           401: //=============================================================================
        !           402: 
        !           403: int MPATH_GetSocketPort (struct qsockaddr *addr)
        !           404: {
        !           405:        return ntohs(((struct sockaddr_in *)addr)->sin_port);
        !           406: }
        !           407: 
        !           408: 
        !           409: int MPATH_SetSocketPort (struct qsockaddr *addr, int port)
        !           410: {
        !           411:        ((struct sockaddr_in *)addr)->sin_port = htons(port);
        !           412:        return 0;
        !           413: }
        !           414: 
        !           415: //=============================================================================

unix.superglobalmegacorp.com

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