Annotation of quake1/net_bw.c, revision 1.1.1.2

1.1       root        1: // net_bw.c
                      2: 
                      3: #include <stdio.h>
                      4: #include <stdlib.h>
                      5: #include <dpmi.h>
                      6: 
                      7: #include "quakedef.h"
                      8: #include "dosisms.h"
                      9: 
                     10: 
                     11: // this section is general Unix stuff that we need
                     12: 
                     13: #define        EIO                             5       /* I/O error */
                     14: #define EBADS                  9
                     15: #define EWOULDBLOCK            35      /* function would block */
                     16: #define EMSGSIZE               40      /* message to big for buffers */
                     17: #define        EPROTONOSUPPORT 43      /* Protocol not supported */
                     18: #define        ESOCKTNOSUPPORT 44      /* Socket type not supported */
                     19: #define        EPFNOSUPPORT    46      /* Protocol family not supported */
                     20: #define EAFNOSUPPORT   47      /* Address family not supported */
                     21: #define ECONNABORTED   53      /* User requested hangup */
                     22: #define ENOBUFS                55      /* No buffers available */
                     23: #define EISCONN                56      /* Socket has closed */
                     24: #define ENOTCONN               57      /* Socket is not connected */
                     25: #define ESHUTDOWN              58      /* Socket is closed */
                     26: #define ETOOMANYREFS   59      /* Too many sockets open */
                     27: #define ETIMEDOUT              60      /* Connection timed out */
                     28: #define ECONNREFUSED   61      /* Connection refused */
                     29: 
                     30: #define AF_INET                2       /* internet */
                     31: 
                     32: #define PF_INET                        AF_INET
                     33: 
                     34: #define SOCK_STREAM            1               /* stream */
                     35: #define SOCK_DGRAM             2               /* datagram */
                     36: 
                     37: #define IPPROTO_TCP            6
                     38: #define IPPROTO_UDP            17
                     39: 
                     40: #define INADDR_ANY             0
                     41: 
                     42: #define SIOCDONE               0x7300
                     43: #define FIONREAD               0x667f
                     44: #define FIONBIO                0x667e
                     45: #define FIONWIN                0x1000
                     46: #define FIONTIN                0x2000
                     47: 
                     48: #define BRDINIT                0
                     49: #define BRDADDR                10
                     50: 
                     51: #define MAXHOSTNAMELEN 256
                     52: 
                     53: #define SOL_SOCKET             0xffff          /* options for socket level */
                     54: 
                     55: /*
                     56:  * Option flags per-socket.
                     57:  */
                     58: #define SO_DEBUG               0x0001          /* turn on debugging info recording */
                     59: #define SO_ACCEPTCONN  0x0002          /* socket has had listen() */
                     60: #define SO_REUSEADDR   0x0004          /* allow local address reuse */
                     61: #define SO_KEEPALIVE   0x0008          /* keep connections alive */
                     62: #define SO_DONTROUTE   0x0010          /* just use interface addresses */
                     63: #define SO_BROADCAST   0x0020          /* permit sending of broadcast msgs */
                     64: #define SO_USELOOPBACK 0x0040          /* bypass hardware when possible */
                     65: #define SO_LINGER              0x0080          /* linger on close if data present */
                     66: #define SO_OOBINLINE   0x0100          /* leave received OOB data in line */
                     67: #define SO_USEPRIV             0x4000          /* allocate from privileged port area */
                     68: #define SO_CANTSIG             0x8000          /* prevent SIGPIPE on SS_CANTSENDMORE */
                     69: 
                     70: /*
                     71:  * Additional options, not kept in so_options.
                     72:  */
                     73: #define SO_SNDBUF              0x1001          /* send buffer size */
                     74: #define SO_RCVBUF              0x1002          /* receive buffer size */
                     75: #define SO_SNDLOWAT            0x1003          /* send low-water mark */
                     76: #define SO_RCVLOWAT            0x1004          /* receive low-water mark */
                     77: #define SO_SNDTIMEO            0x1005          /* send timeout */
                     78: #define SO_RCVTIMEO            0x1006          /* receive timeout */
                     79: #define SO_ERROR               0x1007          /* get error status and clear */
                     80: #define SO_TYPE                        0x1008          /* get socket type */
                     81: 
                     82: 
                     83: struct in_addr
                     84: {
                     85:        union
                     86:        {
                     87:                struct { unsigned char s_b1,s_b2,s_b3,s_b4; } S_un_b;
                     88:                struct { unsigned short s_w1,s_w2; } S_un_w;
                     89:                unsigned long S_addr;
                     90:        } S_un;
                     91: };
                     92: #define        s_addr  S_un.S_addr     /* can be used for most tcp & ip code */
                     93: #define        s_host  S_un.S_un_b.s_b2        /* host on imp */
                     94: #define        s_net   S_un.S_un_b.s_b1        /* network */
                     95: #define        s_imp   S_un.S_un_w.s_w2        /* imp */
                     96: #define        s_impno S_un.S_un_b.s_b4        /* imp # */
                     97: #define        s_lh    S_un.S_un_b.s_b3        /* logical host */
                     98: 
                     99: struct sockaddr_in
                    100: {
                    101:     short                      sin_family;
                    102:     unsigned short     sin_port;
                    103:        struct in_addr  sin_addr;
                    104:     char                       sin_zero[8];
                    105: };
                    106: 
                    107: struct hostent {
                    108:        char    *h_name;        /* official name of host */
                    109:        char    **h_aliases;    /* alias list */
                    110:        int     h_addrtype;     /* host address type */
                    111:        int     h_length;       /* length of address */
                    112:        char    **h_addr_list;  /* list of addresses from name server */
                    113: #define        h_addr  h_addr_list[0]  /* address, for backward compatiblity */
                    114: };
                    115: 
                    116: char *inet_ntoa(struct in_addr in);
                    117: 
                    118: 
                    119: // this section is B&W specific constants & structures
                    120: 
                    121: #define BW_IOCTL_BIND                  0
                    122: #define BW_IOCTL_CLEAROPTIONS  5
                    123: #define BW_IOCTL_SETOPTIONS            6
                    124: #define BW_IOCTL_PEEK                  7
                    125: #define BW_IOCTL_SETWINMASK            8
                    126: 
                    127: #define BW_OPTION_BLOCKING             0x01
                    128: #define BW_OPTION_REUSEBUFFERS 0x80
                    129: 
                    130: #define BW_ERR_USR_HANGUP              50
                    131: #define BW_ERR_HANGUP                  51
                    132: #define BW_ERR_NET_ERR                 52
                    133: #define BW_ERR_IS_CLOSED               53
                    134: #define BW_ERR_TIME_OUT                        54
                    135: #define BW_ERR_RESET                   55
                    136: #define BW_ERR_FULL                            56
                    137: #define BW_ERR_BLOCK                   57
                    138: #define BW_ERR_SHUTDOWN                        58
                    139: 
                    140: #pragma pack(1)
                    141: 
                    142: typedef struct
                    143: {
                    144:        char                    state;                  // always 1
                    145:        short                   localPort;
                    146:        struct in_addr  localAddr;
                    147:        char                    reason;                 // always 0
                    148:        char                    options;
                    149:        short                   dataAvailable;
                    150: } BW_UDPinfo_t;
                    151: 
                    152: typedef struct
                    153: {
                    154:        char                    reserved1 [6];
                    155:        unsigned short  info2Offset;
                    156:        char                    reserved2 [18];
                    157:        struct in_addr  remoteAddr;
                    158: } BW_UDPreadInfo1_t;
                    159: 
                    160: typedef struct
                    161: {
                    162:        short                   remotePort;
                    163:        char                    reserved1 [2];
                    164:        unsigned short  dataLenPlus8;
                    165:        char                    reserved2 [2];
                    166:        char                    data[1];                        // actual size is <dataLenPlus8> - 8            
                    167: } BW_UDPreadInfo2_t;
                    168: 
                    169: typedef struct
                    170: {
                    171:        char                    reserved1 [2];
                    172:        short                   remotePort;
                    173:        unsigned short  dataLen;
                    174:        struct in_addr  remoteAddr;
                    175:        char                    reserved2 [42];
                    176:        char                    data[1];                        // actual size is <datalen>
                    177: } BW_writeInfo_t;
                    178: 
                    179: typedef struct
                    180: {
                    181:        short   ioport;
                    182:        byte    dma;
                    183:        byte    vector;
                    184:        byte    irq;
                    185:        short   bufferSize;
                    186:        short   maxWindow;
                    187:        short   timeZone;
                    188:        byte    myType;
                    189:        int             inetAddr;
                    190:        short   value;
                    191:        byte    subnetMask;
                    192:        short   etherPointer;
                    193:        short   logserverPointer;
                    194:        short   nameserverPointer;
                    195:        short   printserverPointer;
                    196:        short   timeserverPointer;
                    197:        short   gatewayPointer;
                    198:        short   driverSegment;
                    199:        byte    transferSize;
                    200:        char    cardName [9];
                    201: } BW_ethdevinfo_t;
                    202: 
                    203: #pragma pack()
                    204: 
                    205: #define LOWMEM_SIZE    4096
                    206: 
                    207: static unsigned char *lowmem_buffer;
                    208: static int lowmem_bufseg;
                    209: static int lowmem_bufoff;
                    210: static BW_ethdevinfo_t ethdevinfo;
                    211: static int netmask;
                    212: static struct in_addr bcastaddr;
                    213: 
                    214: extern regs_t regs;
                    215: 
1.1.1.2 ! root      216: #define        DEFAULTnet_hostport     26000
        !           217: 
1.1       root      218: static int net_acceptsocket = -1;              // socket for fielding new connections
1.1.1.2 ! root      219: static int net_hostport;                               // udp port number for acceptsocket
1.1       root      220: static int net_controlsocket = 0;
                    221: 
                    222: #include "net_bw.h"
                    223: 
                    224: //=============================================================================
                    225: 
                    226: static int BW_ioctl(int s, char *msg, int msglen)
                    227: {
                    228:        Q_memcpy(lowmem_buffer, msg, msglen);
                    229: 
                    230:        regs.x.ax = 0x4403;
                    231:        regs.x.bx = s;
                    232:        regs.x.cx = msglen;
                    233:        regs.x.dx = lowmem_bufoff;
                    234:        regs.x.ds = lowmem_bufseg;
                    235:        if (dos_int86(0x21))
                    236:                return regs.x.ax;
                    237:        return 0;
                    238: }
                    239: 
                    240: //=============================================================================
                    241: 
                    242: static int BW_TranslateError(int error)
                    243: {
                    244:        switch(error)
                    245:        {
                    246:                case BW_ERR_USR_HANGUP: return ECONNABORTED;
                    247:                case BW_ERR_HANGUP:             return EISCONN;
                    248:                case BW_ERR_NET_ERR:    return ENOTCONN;
                    249:                case BW_ERR_IS_CLOSED:  return ENOTCONN;
                    250:                case BW_ERR_TIME_OUT:   return ETIMEDOUT;
                    251:                case BW_ERR_RESET:              return ECONNREFUSED;
                    252:                case BW_ERR_FULL:               return ETOOMANYREFS;
                    253:                case BW_ERR_BLOCK:              return EWOULDBLOCK;
                    254:                case BW_ERR_SHUTDOWN:   return ESHUTDOWN;
                    255:        }
                    256:        return EIO;
                    257: }
                    258: 
                    259: //=============================================================================
                    260: 
                    261: static int GetEthdevinfo(void)
                    262: {
                    263:        int fd;
                    264: 
                    265:        Q_strcpy((char *)lowmem_buffer, "ETHDEV27");
                    266:        regs.x.ax = 0x3d42;
                    267:        regs.x.ds = lowmem_bufseg;
                    268:        regs.x.dx = lowmem_bufoff;
                    269:        if (dos_int86(0x21))
                    270:                return -1;
                    271:        fd = regs.x.ax;
                    272: 
                    273:        regs.x.ax = 0x4401;
                    274:        regs.x.bx = fd;
                    275:        regs.x.dx = 0x60;
                    276:        dos_int86(0x21);
                    277: 
                    278:        regs.h.ah = 0x3f;
                    279:        regs.x.cx = sizeof(ethdevinfo);
                    280:        regs.x.es = regs.x.ds = lowmem_bufseg;
                    281:        regs.x.dx = lowmem_bufoff;
                    282:        regs.x.bx = fd;
                    283:        if (dos_int86(0x21))
                    284:                return -1;
                    285:        Q_memcpy(&ethdevinfo, lowmem_buffer, regs.x.ax);
                    286: 
                    287:        regs.h.ah = 0x3e;
                    288:        regs.x.bx = fd;
                    289:        dos_int86(0x21);
                    290: 
                    291:        return 0;
                    292: }
                    293: 
                    294: //=============================================================================
                    295: 
                    296: int BW_Init(void)
                    297: {
1.1.1.2 ! root      298:        int p;
1.1       root      299:        struct qsockaddr addr;
                    300:        char *colon;
                    301: 
                    302:        if (COM_CheckParm ("-noudp"))
                    303:                return -1;
                    304: 
                    305:        lowmem_buffer = dos_getmemory(LOWMEM_SIZE);
                    306:        if (!lowmem_buffer)
                    307:                Sys_Error("not enough low memory\n");
                    308:        lowmem_bufoff = ptr2real(lowmem_buffer) & 0xf;
                    309:        lowmem_bufseg = ptr2real(lowmem_buffer) >> 4;
                    310: 
                    311:        if (GetEthdevinfo())
                    312:        {
                    313:                Con_DPrintf("Beame & Whiteside TCP/IP not detected\n");
                    314:                dos_freememory(lowmem_buffer);
                    315:                return -1;
                    316:        }
                    317:        netmask = 0xffffffff >> (32 - ethdevinfo.subnetMask);
                    318:        bcastaddr.s_addr = (ethdevinfo.inetAddr & netmask) | (~netmask);
                    319: 
1.1.1.2 ! root      320:        p = COM_CheckParm ("-udpport");
        !           321:        if (p == 0)
        !           322:                net_hostport = DEFAULTnet_hostport;
        !           323:        else if (p < com_argc-1)
        !           324:                net_hostport = Q_atoi (com_argv[p+1]);
        !           325:        else
        !           326:                Sys_Error ("BW_Init: you must specify a number after -udpport");
        !           327: 
1.1       root      328:        if ((net_controlsocket = BW_OpenSocket (0)) == -1)
                    329:        {
                    330:                dos_freememory(lowmem_buffer);
                    331:                Con_DPrintf ("BW_Init unable to open control socket; disabled\n");
                    332:                return -1;
                    333:        }
                    334: 
                    335:        BW_GetSocketAddr (net_controlsocket, &addr);
                    336:        Q_strcpy(my_tcpip_address,  BW_AddrToString (&addr));
                    337:        colon = Q_strrchr (my_tcpip_address, ':');
                    338:        if (colon)
                    339:                *colon = 0;
                    340: 
                    341:        Con_Printf("BW_Init: UDP initialized\n");
                    342:        tcpipAvailable = true;
                    343: 
                    344:        return net_controlsocket;
                    345: }
                    346: 
                    347: //=============================================================================
                    348: 
                    349: void BW_Shutdown(void)
                    350: {
                    351:        BW_Listen (false);
                    352:        BW_CloseSocket (net_controlsocket);
                    353:        dos_freememory(lowmem_buffer);
                    354: }
                    355: 
                    356: //=============================================================================
                    357: 
                    358: void BW_Listen (qboolean state)
                    359: {
                    360:        // enable listening
                    361:        if (state)
                    362:        {
                    363:                if (net_acceptsocket != -1)
                    364:                        return;
                    365:                if ((net_acceptsocket = BW_OpenSocket (net_hostport)) == -1)
                    366:                        Sys_Error ("BW_Listen: Unable to open accept socket\n");
                    367:                return;
                    368:        }
                    369: 
                    370:        // disable listening
                    371:        if (net_acceptsocket == -1)
                    372:                return;
                    373:        BW_CloseSocket (net_acceptsocket);
                    374:        net_acceptsocket = -1;
                    375: }
                    376: 
                    377: 
                    378: //=============================================================================
                    379: 
                    380: /*
                    381: OpenSocket returns a handle to a network socket that has been opened,
                    382: set to nonblocking, and bound to <port>.  Additional socket options
                    383: should be set here if they are needed.  -1 is returned on failure.
                    384: */
                    385: 
                    386: int BW_OpenSocket(int port)
                    387: {
                    388:        int s;
                    389:        int ret;
                    390:        int deadman = 3 * 1024;
                    391:        static int dynamic = 1024;
                    392:        static char reuse_msg[2] = {BW_IOCTL_SETOPTIONS, BW_OPTION_REUSEBUFFERS};
                    393:        static char bind_msg[3] = {BW_IOCTL_BIND, 0, 0};
                    394:        static char nonblock_msg[2] = {BW_IOCTL_CLEAROPTIONS, BW_OPTION_BLOCKING};
                    395: 
                    396:        // allocate a UDP socket
                    397:        Q_strcpy((char *)lowmem_buffer, "UDP-IP10");
                    398:        regs.x.ax = 0x3d42;
                    399:        regs.x.ds = lowmem_bufseg;
                    400:        regs.x.dx = lowmem_bufoff;
                    401:        if (dos_int86(0x21))
                    402:        {
                    403:                Con_Printf("BW_OpenSocket failed: %u\n", BW_TranslateError(regs.x.ax));
                    404:                return -1;
                    405:        }
                    406:        s = regs.x.ax;
                    407: 
                    408:        // set file descriptor to raw mode
                    409:        regs.x.ax = 0x4401;
                    410:        regs.x.bx = s;
                    411:        regs.x.dx = 0x60;
                    412:        dos_int86(0x21);
                    413: 
                    414:        if (BW_ioctl(s, reuse_msg, 2))
                    415:        {
                    416:                Con_Printf("BW_OpenSocket ioctl(reuse) failed\n");
                    417:                return -1;
                    418:        }
                    419: 
                    420:        if (BW_ioctl(s, nonblock_msg, 2))
                    421:        {
                    422:                Con_Printf("BW_OpenSocket ioctl(nonblocking) failed\n");
                    423:                return -1;
                    424:        }
                    425: 
                    426:        // if a socket was specified, bind to it and return
                    427:        if (port)
                    428:        {
                    429:                *(short *)&bind_msg[1] = port;
                    430:                if (BW_ioctl(s, bind_msg, 3))
                    431:                {
                    432:                        BW_CloseSocket(s);
                    433:                        return -1;
                    434:                }
                    435:                return s;
                    436:        }
                    437: 
                    438:        // B&W does NOT do dynamic allocation, so if port == 0 we must fake it
                    439:        do
                    440:        {
                    441:                port = dynamic++;
                    442:                if (dynamic == 4096)
                    443:                        dynamic = 1024;
                    444:                deadman--;
                    445:                *(short *)&bind_msg[1] = port;
                    446:                ret = BW_ioctl(s, bind_msg, 3);
                    447:        }
                    448:        while (ret && deadman);
                    449:        if (ret)
                    450:                return -1;
                    451:        return s;
                    452: }
                    453: 
                    454: //=============================================================================
                    455: 
                    456: int BW_CloseSocket(int socket)
                    457: {
                    458:        regs.h.ah = 0x3e;
                    459:        regs.x.bx = socket;
                    460:        if(dos_int86(0x21))
                    461:                {
                    462:                        Con_Printf("BW_CloseSocket %u failed: %u\n", socket, BW_TranslateError(regs.x.ax));
                    463:                        return -1;
                    464:                }
                    465:        return 0;
                    466: }
                    467: 
                    468: //=============================================================================
                    469: 
                    470: int BW_Connect (int socket, struct qsockaddr *hostaddr)
                    471: {
                    472:        return 0;
                    473: }
                    474: 
                    475: //=============================================================================
                    476: 
                    477: int BW_CheckNewConnections(void)
                    478: {
                    479:        if (net_acceptsocket == 0)
                    480:                return -1;
                    481: 
                    482:        // see if there's anything waiting
                    483:        regs.x.ax = 0x4406;
                    484:        regs.x.bx = net_acceptsocket;
                    485:        dos_int86(0x21);
                    486:        if (regs.x.ax == 0)
                    487:                return -1;
                    488:        return net_acceptsocket;
                    489: }
                    490: 
                    491: //=============================================================================
                    492: 
                    493: int BW_Read(int s, byte *buf, int len, struct qsockaddr *from)
                    494: {
                    495:        BW_UDPreadInfo1_t *info1;
                    496:        BW_UDPreadInfo2_t *info2;
                    497: 
                    498:        // ask if there's anything waiting
                    499:        regs.x.ax = 0x4406;
                    500:        regs.x.bx = s;
                    501:        dos_int86(0x21);
                    502:        if (regs.x.ax == 0)
                    503:                return 0;
                    504: 
                    505:        // there was, so let's get it
                    506:        regs.h.ah = 0x3f;
                    507:        regs.x.cx = /* len + 53 */ LOWMEM_SIZE;
                    508:        regs.x.es = regs.x.ds = lowmem_bufseg;
                    509:        regs.x.dx = lowmem_bufoff;
                    510:        regs.x.bx = s;
                    511:        if (dos_int86(0x21))
                    512:        {
                    513:                Con_Printf("BW UDP read error: %u\n", BW_TranslateError(regs.x.ax));
                    514:                return -1;
                    515:        }
                    516: 
                    517:        info1 = (BW_UDPreadInfo1_t *)lowmem_buffer;
                    518:        info2 = (BW_UDPreadInfo2_t *)(lowmem_buffer + info1->info2Offset);
                    519: 
                    520:        if (from)
                    521:        {
                    522:                from->sa_family = AF_INET;
                    523:                ((struct sockaddr_in *)from)->sin_addr = info1->remoteAddr;
                    524:                ((struct sockaddr_in *)from)->sin_port = htons(info2->remotePort);
                    525:        }
                    526: 
                    527:        len = info2->dataLenPlus8 - 8;
                    528:        if (len > NET_DATAGRAMSIZE)
                    529:        {
                    530:                Con_Printf("BW UDP read packet too large: %u\n", len);
                    531:                return -1;
                    532:        }
                    533:        Q_memcpy(buf, info2->data, len);
                    534: 
                    535:        return len;
                    536: }
                    537: 
                    538: //=============================================================================
                    539: 
                    540: int BW_Broadcast(int s, byte *msg, int len)
                    541: {
                    542:        BW_writeInfo_t *writeInfo;
                    543: 
                    544:        // ask if we're clear to send
                    545:        regs.x.ax = 0x4407;
                    546:        regs.x.bx = s;
                    547:        dos_int86(0x21);
                    548:        if (regs.x.ax == 0)
                    549:                return 0;
                    550: 
                    551:        // yes, let's do it
                    552:        writeInfo = (BW_writeInfo_t *)lowmem_buffer;
                    553:        writeInfo->remoteAddr = bcastaddr;
                    554:        writeInfo->remotePort = net_hostport;
                    555:        writeInfo->dataLen = len;
                    556:        if (len > NET_DATAGRAMSIZE)
                    557:                Sys_Error("BW UDP write packet too large: %u\n", len);
                    558:        Q_memcpy(writeInfo->data, msg, len);
                    559:        writeInfo->data[len] = 0;
                    560:        regs.h.ah = 0x40;
                    561:        regs.x.bx = s;
                    562:        regs.x.cx = len + sizeof(BW_writeInfo_t);
                    563:        regs.x.es = regs.x.ds = lowmem_bufseg;
                    564:        regs.x.dx = lowmem_bufoff;
                    565:        if (dos_int86(0x21))
                    566:        {
                    567:                Con_Printf("BW_Broadcast failed: %u\n", BW_TranslateError(regs.x.ax));
                    568:                return -1;
                    569:        }
                    570: 
                    571:        return len;
                    572: }
                    573: 
                    574: //=============================================================================
                    575: 
                    576: int BW_Write(int s, byte *msg, int len, struct qsockaddr *to)
                    577: {
                    578:        BW_writeInfo_t *writeInfo;
                    579: 
                    580:        // ask if we're clear to send
                    581:        regs.x.ax = 0x4407;
                    582:        regs.x.bx = s;
                    583:        dos_int86(0x21);
                    584:        if (regs.x.ax == 0)
                    585:                return 0;
                    586: 
                    587:        // yes, let's do it
                    588:        writeInfo = (BW_writeInfo_t *)lowmem_buffer;
                    589:        writeInfo->remoteAddr = ((struct sockaddr_in *)to)->sin_addr;
                    590:        writeInfo->remotePort = ntohs(((struct sockaddr_in *)to)->sin_port);
                    591:        writeInfo->dataLen = len;
                    592:        if (len > NET_DATAGRAMSIZE)
                    593:                Sys_Error("BW UDP write packet too large: %u\n", len);
                    594:        Q_memcpy(writeInfo->data, msg, len);
                    595:        writeInfo->data[len] = 0;
                    596:        regs.h.ah = 0x40;
                    597:        regs.x.bx = s;
                    598:        regs.x.cx = len + sizeof(BW_writeInfo_t);
                    599:        regs.x.es = regs.x.ds = lowmem_bufseg;
                    600:        regs.x.dx = lowmem_bufoff;
                    601:        if (dos_int86(0x21))
                    602:        {
                    603:                Con_Printf("BW_Write failed: %u\n", BW_TranslateError(regs.x.ax));
                    604:                return -1;
                    605:        }
                    606: 
                    607:        return len;
                    608: }
                    609: 
                    610: //=============================================================================
                    611: 
                    612: 
                    613: char *BW_AddrToString (struct qsockaddr *addr)
                    614: {
                    615:        static char buffer[22];
                    616: 
                    617:        sprintf(buffer, "%d.%d.%d.%d:%d",
                    618:                ((struct sockaddr_in *)addr)->sin_addr.s_net,
                    619:                ((struct sockaddr_in *)addr)->sin_addr.s_host,
                    620:                ((struct sockaddr_in *)addr)->sin_addr.s_lh,
                    621:                ((struct sockaddr_in *)addr)->sin_addr.s_impno,
                    622:                ntohs(((struct sockaddr_in *)addr)->sin_port)
                    623:                );
                    624:        return buffer;
                    625: }
                    626: 
                    627: //=============================================================================
                    628: 
                    629: int BW_StringToAddr (char *string, struct qsockaddr *addr)
                    630: {
                    631:        int ha1, ha2, ha3, ha4, hp;
                    632:        int ipaddr;
                    633: 
                    634:        sscanf(string, "%d.%d.%d.%d:%d", &ha1, &ha2, &ha3, &ha4, &hp);
                    635:        ipaddr = (ha1 << 24) | (ha2 << 16) | (ha3 << 8) | ha4;
                    636: 
                    637:        addr->sa_family = AF_INET;
                    638:        ((struct sockaddr_in *)addr)->sin_addr.s_addr = htonl(ipaddr);
                    639:        ((struct sockaddr_in *)addr)->sin_port = htons((short)hp);
                    640:        return 0;
                    641: }
                    642: 
                    643: //=============================================================================
                    644: 
                    645: int BW_GetSocketAddr (int socket, struct qsockaddr *addr)
                    646: {
                    647:        regs.x.ax = 0x4402;
                    648:        regs.x.bx = socket;
                    649:        regs.x.cx = sizeof(BW_UDPinfo_t);
                    650:        regs.x.dx = lowmem_bufoff;
                    651:        regs.x.ds = lowmem_bufseg;
                    652:        dos_int86(0x21);
                    653: 
                    654:        addr->sa_family = AF_INET;
                    655:        ((struct sockaddr_in *)addr)->sin_addr.s_addr = ((BW_UDPinfo_t *)lowmem_buffer)->localAddr.s_addr;
                    656:        ((struct sockaddr_in *)addr)->sin_port = htons(((BW_UDPinfo_t *)lowmem_buffer)->localPort);
                    657: 
                    658:        return 0;
                    659: }
                    660: 
                    661: //=============================================================================
                    662: 
                    663: int BW_GetNameFromAddr (struct qsockaddr *addr, char *name)
                    664: {
                    665:        Q_strcpy(name, BW_AddrToString(addr));
                    666:        return 0;
                    667: }
                    668: 
                    669: ///=============================================================================
                    670: 
                    671: int BW_GetAddrFromName (char *name, struct qsockaddr *hostaddr)
                    672: {
                    673:        char buff[MAXHOSTNAMELEN];
                    674:        char *b;
                    675:        int addr;
                    676:        int num;
                    677:        int mask;
                    678:        int run;
                    679:        int port;
                    680: 
                    681:        if (name[0] < '0' || name[0] > '9')
                    682:                return -1;
                    683: 
                    684:        buff[0] = '.';
                    685:        b = buff;
                    686:        Q_strcpy(buff+1, name);
                    687:        if (buff[1] == '.')
                    688:                b++;
                    689: 
                    690:        addr = 0;
                    691:        mask = -1;
1.1.1.2 ! root      692:        while (*b++ == '.')
1.1       root      693:        {
                    694:                num = 0;
                    695:                run = 0;
                    696:                while (!( *b < '0' || *b > '9'))
                    697:                {
                    698:                  num = num*10 + *b++ - '0';
                    699:                  if (++run > 3)
                    700:                        return -1;
                    701:                }
                    702:                if ((*b < '0' || *b > '9') && *b != '.' && *b != ':' && *b != 0)
                    703:                        return -1;
                    704:                if (num < 0 || num > 255)
                    705:                        return -1;
                    706:                mask<<=8;
                    707:                addr = (addr<<8) + num;
                    708:        }
                    709:        addr = htonl(addr);
                    710:        mask = htonl(mask);
                    711: 
                    712:        if (*b++ == ':')
                    713:                port = Q_atoi(b);
                    714:        else
                    715:                port = net_hostport;
                    716: 
                    717:        hostaddr->sa_family = AF_INET;
                    718:        ((struct sockaddr_in *)hostaddr)->sin_port = htons((short)port);        
                    719:        ((struct sockaddr_in *)hostaddr)->sin_addr.s_addr =
                    720:        ((ethdevinfo.inetAddr & mask) | addr);
                    721: 
                    722:        return 0;
                    723: }
                    724: 
                    725: //=============================================================================
                    726: 
                    727: int BW_AddrCompare (struct qsockaddr *addr1, struct qsockaddr *addr2)
                    728: {
                    729:        if (addr1->sa_family != addr2->sa_family)
                    730:                return -1;
                    731: 
                    732:        if (((struct sockaddr_in *)addr1)->sin_addr.s_addr != ((struct sockaddr_in *)addr2)->sin_addr.s_addr)
                    733:                return -1;
                    734: 
                    735:        if (((struct sockaddr_in *)addr1)->sin_port != ((struct sockaddr_in *)addr2)->sin_port)
                    736:                return 1;
                    737: 
                    738:        return 0;
                    739: }
                    740: 
                    741: //=============================================================================
                    742: 
                    743: int BW_GetSocketPort (struct qsockaddr *addr)
                    744: {
                    745:        return ntohs(((struct sockaddr_in *)addr)->sin_port);
                    746: }
                    747: 
                    748: 
                    749: int BW_SetSocketPort (struct qsockaddr *addr, int port)
                    750: {
                    751:        ((struct sockaddr_in *)addr)->sin_port = htons(port);
                    752:        return 0;
                    753: }
                    754: 
                    755: //=============================================================================

unix.superglobalmegacorp.com

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