Annotation of quake1/net_bw.c, revision 1.1.1.3

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: 
                    216: static int net_acceptsocket = -1;              // socket for fielding new connections
                    217: static int net_controlsocket = 0;
                    218: 
                    219: #include "net_bw.h"
                    220: 
                    221: //=============================================================================
                    222: 
                    223: static int BW_ioctl(int s, char *msg, int msglen)
                    224: {
                    225:        Q_memcpy(lowmem_buffer, msg, msglen);
                    226: 
                    227:        regs.x.ax = 0x4403;
                    228:        regs.x.bx = s;
                    229:        regs.x.cx = msglen;
                    230:        regs.x.dx = lowmem_bufoff;
                    231:        regs.x.ds = lowmem_bufseg;
                    232:        if (dos_int86(0x21))
                    233:                return regs.x.ax;
                    234:        return 0;
                    235: }
                    236: 
                    237: //=============================================================================
                    238: 
                    239: static int BW_TranslateError(int error)
                    240: {
                    241:        switch(error)
                    242:        {
                    243:                case BW_ERR_USR_HANGUP: return ECONNABORTED;
                    244:                case BW_ERR_HANGUP:             return EISCONN;
                    245:                case BW_ERR_NET_ERR:    return ENOTCONN;
                    246:                case BW_ERR_IS_CLOSED:  return ENOTCONN;
                    247:                case BW_ERR_TIME_OUT:   return ETIMEDOUT;
                    248:                case BW_ERR_RESET:              return ECONNREFUSED;
                    249:                case BW_ERR_FULL:               return ETOOMANYREFS;
                    250:                case BW_ERR_BLOCK:              return EWOULDBLOCK;
                    251:                case BW_ERR_SHUTDOWN:   return ESHUTDOWN;
                    252:        }
                    253:        return EIO;
                    254: }
                    255: 
                    256: //=============================================================================
                    257: 
                    258: static int GetEthdevinfo(void)
                    259: {
                    260:        int fd;
                    261: 
                    262:        Q_strcpy((char *)lowmem_buffer, "ETHDEV27");
                    263:        regs.x.ax = 0x3d42;
                    264:        regs.x.ds = lowmem_bufseg;
                    265:        regs.x.dx = lowmem_bufoff;
                    266:        if (dos_int86(0x21))
                    267:                return -1;
                    268:        fd = regs.x.ax;
                    269: 
                    270:        regs.x.ax = 0x4401;
                    271:        regs.x.bx = fd;
                    272:        regs.x.dx = 0x60;
                    273:        dos_int86(0x21);
                    274: 
                    275:        regs.h.ah = 0x3f;
                    276:        regs.x.cx = sizeof(ethdevinfo);
                    277:        regs.x.es = regs.x.ds = lowmem_bufseg;
                    278:        regs.x.dx = lowmem_bufoff;
                    279:        regs.x.bx = fd;
                    280:        if (dos_int86(0x21))
                    281:                return -1;
                    282:        Q_memcpy(&ethdevinfo, lowmem_buffer, regs.x.ax);
                    283: 
                    284:        regs.h.ah = 0x3e;
                    285:        regs.x.bx = fd;
                    286:        dos_int86(0x21);
                    287: 
                    288:        return 0;
                    289: }
                    290: 
                    291: //=============================================================================
                    292: 
                    293: int BW_Init(void)
                    294: {
                    295:        struct qsockaddr addr;
                    296:        char *colon;
                    297: 
                    298:        if (COM_CheckParm ("-noudp"))
                    299:                return -1;
                    300: 
                    301:        lowmem_buffer = dos_getmemory(LOWMEM_SIZE);
                    302:        if (!lowmem_buffer)
                    303:                Sys_Error("not enough low memory\n");
                    304:        lowmem_bufoff = ptr2real(lowmem_buffer) & 0xf;
                    305:        lowmem_bufseg = ptr2real(lowmem_buffer) >> 4;
                    306: 
                    307:        if (GetEthdevinfo())
                    308:        {
                    309:                Con_DPrintf("Beame & Whiteside TCP/IP not detected\n");
                    310:                dos_freememory(lowmem_buffer);
                    311:                return -1;
                    312:        }
                    313:        netmask = 0xffffffff >> (32 - ethdevinfo.subnetMask);
                    314:        bcastaddr.s_addr = (ethdevinfo.inetAddr & netmask) | (~netmask);
                    315: 
                    316:        if ((net_controlsocket = BW_OpenSocket (0)) == -1)
                    317:        {
                    318:                dos_freememory(lowmem_buffer);
                    319:                Con_DPrintf ("BW_Init unable to open control socket; disabled\n");
                    320:                return -1;
                    321:        }
                    322: 
                    323:        BW_GetSocketAddr (net_controlsocket, &addr);
                    324:        Q_strcpy(my_tcpip_address,  BW_AddrToString (&addr));
                    325:        colon = Q_strrchr (my_tcpip_address, ':');
                    326:        if (colon)
                    327:                *colon = 0;
                    328: 
                    329:        Con_Printf("BW_Init: UDP initialized\n");
                    330:        tcpipAvailable = true;
                    331: 
                    332:        return net_controlsocket;
                    333: }
                    334: 
                    335: //=============================================================================
                    336: 
                    337: void BW_Shutdown(void)
                    338: {
                    339:        BW_Listen (false);
                    340:        BW_CloseSocket (net_controlsocket);
                    341:        dos_freememory(lowmem_buffer);
                    342: }
                    343: 
                    344: //=============================================================================
                    345: 
                    346: void BW_Listen (qboolean state)
                    347: {
                    348:        // enable listening
                    349:        if (state)
                    350:        {
                    351:                if (net_acceptsocket != -1)
                    352:                        return;
                    353:                if ((net_acceptsocket = BW_OpenSocket (net_hostport)) == -1)
                    354:                        Sys_Error ("BW_Listen: Unable to open accept socket\n");
                    355:                return;
                    356:        }
                    357: 
                    358:        // disable listening
                    359:        if (net_acceptsocket == -1)
                    360:                return;
                    361:        BW_CloseSocket (net_acceptsocket);
                    362:        net_acceptsocket = -1;
                    363: }
                    364: 
                    365: 
                    366: //=============================================================================
                    367: 
                    368: /*
                    369: OpenSocket returns a handle to a network socket that has been opened,
                    370: set to nonblocking, and bound to <port>.  Additional socket options
                    371: should be set here if they are needed.  -1 is returned on failure.
                    372: */
                    373: 
                    374: int BW_OpenSocket(int port)
                    375: {
                    376:        int s;
                    377:        int ret;
                    378:        int deadman = 3 * 1024;
                    379:        static int dynamic = 1024;
                    380:        static char reuse_msg[2] = {BW_IOCTL_SETOPTIONS, BW_OPTION_REUSEBUFFERS};
                    381:        static char bind_msg[3] = {BW_IOCTL_BIND, 0, 0};
                    382:        static char nonblock_msg[2] = {BW_IOCTL_CLEAROPTIONS, BW_OPTION_BLOCKING};
                    383: 
                    384:        // allocate a UDP socket
                    385:        Q_strcpy((char *)lowmem_buffer, "UDP-IP10");
                    386:        regs.x.ax = 0x3d42;
                    387:        regs.x.ds = lowmem_bufseg;
                    388:        regs.x.dx = lowmem_bufoff;
                    389:        if (dos_int86(0x21))
                    390:        {
                    391:                Con_Printf("BW_OpenSocket failed: %u\n", BW_TranslateError(regs.x.ax));
                    392:                return -1;
                    393:        }
                    394:        s = regs.x.ax;
                    395: 
                    396:        // set file descriptor to raw mode
                    397:        regs.x.ax = 0x4401;
                    398:        regs.x.bx = s;
                    399:        regs.x.dx = 0x60;
                    400:        dos_int86(0x21);
                    401: 
                    402:        if (BW_ioctl(s, reuse_msg, 2))
                    403:        {
                    404:                Con_Printf("BW_OpenSocket ioctl(reuse) failed\n");
                    405:                return -1;
                    406:        }
                    407: 
                    408:        if (BW_ioctl(s, nonblock_msg, 2))
                    409:        {
                    410:                Con_Printf("BW_OpenSocket ioctl(nonblocking) failed\n");
                    411:                return -1;
                    412:        }
                    413: 
                    414:        // if a socket was specified, bind to it and return
                    415:        if (port)
                    416:        {
                    417:                *(short *)&bind_msg[1] = port;
                    418:                if (BW_ioctl(s, bind_msg, 3))
                    419:                {
                    420:                        BW_CloseSocket(s);
                    421:                        return -1;
                    422:                }
                    423:                return s;
                    424:        }
                    425: 
                    426:        // B&W does NOT do dynamic allocation, so if port == 0 we must fake it
                    427:        do
                    428:        {
                    429:                port = dynamic++;
                    430:                if (dynamic == 4096)
                    431:                        dynamic = 1024;
                    432:                deadman--;
                    433:                *(short *)&bind_msg[1] = port;
                    434:                ret = BW_ioctl(s, bind_msg, 3);
                    435:        }
                    436:        while (ret && deadman);
                    437:        if (ret)
                    438:                return -1;
                    439:        return s;
                    440: }
                    441: 
                    442: //=============================================================================
                    443: 
                    444: int BW_CloseSocket(int socket)
                    445: {
                    446:        regs.h.ah = 0x3e;
                    447:        regs.x.bx = socket;
                    448:        if(dos_int86(0x21))
                    449:                {
                    450:                        Con_Printf("BW_CloseSocket %u failed: %u\n", socket, BW_TranslateError(regs.x.ax));
                    451:                        return -1;
                    452:                }
                    453:        return 0;
                    454: }
                    455: 
                    456: //=============================================================================
                    457: 
                    458: int BW_Connect (int socket, struct qsockaddr *hostaddr)
                    459: {
                    460:        return 0;
                    461: }
                    462: 
                    463: //=============================================================================
                    464: 
                    465: int BW_CheckNewConnections(void)
                    466: {
                    467:        if (net_acceptsocket == 0)
                    468:                return -1;
                    469: 
                    470:        // see if there's anything waiting
                    471:        regs.x.ax = 0x4406;
                    472:        regs.x.bx = net_acceptsocket;
                    473:        dos_int86(0x21);
                    474:        if (regs.x.ax == 0)
                    475:                return -1;
                    476:        return net_acceptsocket;
                    477: }
                    478: 
                    479: //=============================================================================
                    480: 
                    481: int BW_Read(int s, byte *buf, int len, struct qsockaddr *from)
                    482: {
                    483:        BW_UDPreadInfo1_t *info1;
                    484:        BW_UDPreadInfo2_t *info2;
                    485: 
                    486:        // ask if there's anything waiting
                    487:        regs.x.ax = 0x4406;
                    488:        regs.x.bx = s;
                    489:        dos_int86(0x21);
                    490:        if (regs.x.ax == 0)
                    491:                return 0;
                    492: 
                    493:        // there was, so let's get it
                    494:        regs.h.ah = 0x3f;
                    495:        regs.x.cx = /* len + 53 */ LOWMEM_SIZE;
                    496:        regs.x.es = regs.x.ds = lowmem_bufseg;
                    497:        regs.x.dx = lowmem_bufoff;
                    498:        regs.x.bx = s;
                    499:        if (dos_int86(0x21))
                    500:        {
                    501:                Con_Printf("BW UDP read error: %u\n", BW_TranslateError(regs.x.ax));
                    502:                return -1;
                    503:        }
                    504: 
                    505:        info1 = (BW_UDPreadInfo1_t *)lowmem_buffer;
                    506:        info2 = (BW_UDPreadInfo2_t *)(lowmem_buffer + info1->info2Offset);
                    507: 
                    508:        if (from)
                    509:        {
                    510:                from->sa_family = AF_INET;
                    511:                ((struct sockaddr_in *)from)->sin_addr = info1->remoteAddr;
                    512:                ((struct sockaddr_in *)from)->sin_port = htons(info2->remotePort);
                    513:        }
                    514: 
                    515:        len = info2->dataLenPlus8 - 8;
                    516:        if (len > NET_DATAGRAMSIZE)
                    517:        {
                    518:                Con_Printf("BW UDP read packet too large: %u\n", len);
                    519:                return -1;
                    520:        }
                    521:        Q_memcpy(buf, info2->data, len);
                    522: 
                    523:        return len;
                    524: }
                    525: 
                    526: //=============================================================================
                    527: 
                    528: int BW_Broadcast(int s, byte *msg, int len)
                    529: {
                    530:        BW_writeInfo_t *writeInfo;
                    531: 
                    532:        // ask if we're clear to send
                    533:        regs.x.ax = 0x4407;
                    534:        regs.x.bx = s;
                    535:        dos_int86(0x21);
                    536:        if (regs.x.ax == 0)
                    537:                return 0;
                    538: 
                    539:        // yes, let's do it
                    540:        writeInfo = (BW_writeInfo_t *)lowmem_buffer;
                    541:        writeInfo->remoteAddr = bcastaddr;
                    542:        writeInfo->remotePort = net_hostport;
                    543:        writeInfo->dataLen = len;
                    544:        if (len > NET_DATAGRAMSIZE)
                    545:                Sys_Error("BW UDP write packet too large: %u\n", len);
                    546:        Q_memcpy(writeInfo->data, msg, len);
                    547:        writeInfo->data[len] = 0;
                    548:        regs.h.ah = 0x40;
                    549:        regs.x.bx = s;
                    550:        regs.x.cx = len + sizeof(BW_writeInfo_t);
                    551:        regs.x.es = regs.x.ds = lowmem_bufseg;
                    552:        regs.x.dx = lowmem_bufoff;
                    553:        if (dos_int86(0x21))
                    554:        {
                    555:                Con_Printf("BW_Broadcast failed: %u\n", BW_TranslateError(regs.x.ax));
                    556:                return -1;
                    557:        }
                    558: 
                    559:        return len;
                    560: }
                    561: 
                    562: //=============================================================================
                    563: 
                    564: int BW_Write(int s, byte *msg, int len, struct qsockaddr *to)
                    565: {
                    566:        BW_writeInfo_t *writeInfo;
                    567: 
                    568:        // ask if we're clear to send
                    569:        regs.x.ax = 0x4407;
                    570:        regs.x.bx = s;
                    571:        dos_int86(0x21);
                    572:        if (regs.x.ax == 0)
                    573:                return 0;
                    574: 
                    575:        // yes, let's do it
                    576:        writeInfo = (BW_writeInfo_t *)lowmem_buffer;
                    577:        writeInfo->remoteAddr = ((struct sockaddr_in *)to)->sin_addr;
                    578:        writeInfo->remotePort = ntohs(((struct sockaddr_in *)to)->sin_port);
                    579:        writeInfo->dataLen = len;
                    580:        if (len > NET_DATAGRAMSIZE)
                    581:                Sys_Error("BW UDP write packet too large: %u\n", len);
                    582:        Q_memcpy(writeInfo->data, msg, len);
                    583:        writeInfo->data[len] = 0;
                    584:        regs.h.ah = 0x40;
                    585:        regs.x.bx = s;
                    586:        regs.x.cx = len + sizeof(BW_writeInfo_t);
                    587:        regs.x.es = regs.x.ds = lowmem_bufseg;
                    588:        regs.x.dx = lowmem_bufoff;
                    589:        if (dos_int86(0x21))
                    590:        {
                    591:                Con_Printf("BW_Write failed: %u\n", BW_TranslateError(regs.x.ax));
                    592:                return -1;
                    593:        }
                    594: 
                    595:        return len;
                    596: }
                    597: 
                    598: //=============================================================================
                    599: 
                    600: 
                    601: char *BW_AddrToString (struct qsockaddr *addr)
                    602: {
                    603:        static char buffer[22];
                    604: 
                    605:        sprintf(buffer, "%d.%d.%d.%d:%d",
                    606:                ((struct sockaddr_in *)addr)->sin_addr.s_net,
                    607:                ((struct sockaddr_in *)addr)->sin_addr.s_host,
                    608:                ((struct sockaddr_in *)addr)->sin_addr.s_lh,
                    609:                ((struct sockaddr_in *)addr)->sin_addr.s_impno,
                    610:                ntohs(((struct sockaddr_in *)addr)->sin_port)
                    611:                );
                    612:        return buffer;
                    613: }
                    614: 
                    615: //=============================================================================
                    616: 
                    617: int BW_StringToAddr (char *string, struct qsockaddr *addr)
                    618: {
                    619:        int ha1, ha2, ha3, ha4, hp;
                    620:        int ipaddr;
                    621: 
                    622:        sscanf(string, "%d.%d.%d.%d:%d", &ha1, &ha2, &ha3, &ha4, &hp);
                    623:        ipaddr = (ha1 << 24) | (ha2 << 16) | (ha3 << 8) | ha4;
                    624: 
                    625:        addr->sa_family = AF_INET;
                    626:        ((struct sockaddr_in *)addr)->sin_addr.s_addr = htonl(ipaddr);
                    627:        ((struct sockaddr_in *)addr)->sin_port = htons((short)hp);
                    628:        return 0;
                    629: }
                    630: 
                    631: //=============================================================================
                    632: 
                    633: int BW_GetSocketAddr (int socket, struct qsockaddr *addr)
                    634: {
                    635:        regs.x.ax = 0x4402;
                    636:        regs.x.bx = socket;
                    637:        regs.x.cx = sizeof(BW_UDPinfo_t);
                    638:        regs.x.dx = lowmem_bufoff;
                    639:        regs.x.ds = lowmem_bufseg;
                    640:        dos_int86(0x21);
                    641: 
                    642:        addr->sa_family = AF_INET;
                    643:        ((struct sockaddr_in *)addr)->sin_addr.s_addr = ((BW_UDPinfo_t *)lowmem_buffer)->localAddr.s_addr;
                    644:        ((struct sockaddr_in *)addr)->sin_port = htons(((BW_UDPinfo_t *)lowmem_buffer)->localPort);
                    645: 
                    646:        return 0;
                    647: }
                    648: 
                    649: //=============================================================================
                    650: 
                    651: int BW_GetNameFromAddr (struct qsockaddr *addr, char *name)
                    652: {
                    653:        Q_strcpy(name, BW_AddrToString(addr));
                    654:        return 0;
                    655: }
                    656: 
                    657: ///=============================================================================
                    658: 
                    659: int BW_GetAddrFromName (char *name, struct qsockaddr *hostaddr)
                    660: {
                    661:        char buff[MAXHOSTNAMELEN];
                    662:        char *b;
                    663:        int addr;
                    664:        int num;
                    665:        int mask;
                    666:        int run;
                    667:        int port;
                    668: 
                    669:        if (name[0] < '0' || name[0] > '9')
                    670:                return -1;
                    671: 
                    672:        buff[0] = '.';
                    673:        b = buff;
                    674:        Q_strcpy(buff+1, name);
                    675:        if (buff[1] == '.')
                    676:                b++;
                    677: 
                    678:        addr = 0;
                    679:        mask = -1;
1.1.1.3 ! root      680:        while (*b == '.')
1.1       root      681:        {
1.1.1.3 ! root      682:                b++;
1.1       root      683:                num = 0;
                    684:                run = 0;
                    685:                while (!( *b < '0' || *b > '9'))
                    686:                {
                    687:                  num = num*10 + *b++ - '0';
                    688:                  if (++run > 3)
                    689:                        return -1;
                    690:                }
                    691:                if ((*b < '0' || *b > '9') && *b != '.' && *b != ':' && *b != 0)
                    692:                        return -1;
                    693:                if (num < 0 || num > 255)
                    694:                        return -1;
                    695:                mask<<=8;
                    696:                addr = (addr<<8) + num;
                    697:        }
                    698:        addr = htonl(addr);
                    699:        mask = htonl(mask);
                    700: 
                    701:        if (*b++ == ':')
                    702:                port = Q_atoi(b);
                    703:        else
                    704:                port = net_hostport;
                    705: 
                    706:        hostaddr->sa_family = AF_INET;
                    707:        ((struct sockaddr_in *)hostaddr)->sin_port = htons((short)port);        
                    708:        ((struct sockaddr_in *)hostaddr)->sin_addr.s_addr =
                    709:        ((ethdevinfo.inetAddr & mask) | addr);
                    710: 
                    711:        return 0;
                    712: }
                    713: 
                    714: //=============================================================================
                    715: 
                    716: int BW_AddrCompare (struct qsockaddr *addr1, struct qsockaddr *addr2)
                    717: {
                    718:        if (addr1->sa_family != addr2->sa_family)
                    719:                return -1;
                    720: 
                    721:        if (((struct sockaddr_in *)addr1)->sin_addr.s_addr != ((struct sockaddr_in *)addr2)->sin_addr.s_addr)
                    722:                return -1;
                    723: 
                    724:        if (((struct sockaddr_in *)addr1)->sin_port != ((struct sockaddr_in *)addr2)->sin_port)
                    725:                return 1;
                    726: 
                    727:        return 0;
                    728: }
                    729: 
                    730: //=============================================================================
                    731: 
                    732: int BW_GetSocketPort (struct qsockaddr *addr)
                    733: {
                    734:        return ntohs(((struct sockaddr_in *)addr)->sin_port);
                    735: }
                    736: 
                    737: 
                    738: int BW_SetSocketPort (struct qsockaddr *addr, int port)
                    739: {
                    740:        ((struct sockaddr_in *)addr)->sin_port = htons(port);
                    741:        return 0;
                    742: }
                    743: 
                    744: //=============================================================================

unix.superglobalmegacorp.com

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