these aren't supported anymore (not as if they're /really/ gone)

This commit is contained in:
Bill Currie 2003-02-10 21:56:04 +00:00
parent f4fdbeee4d
commit 80002a5151
7 changed files with 1 additions and 2706 deletions

View file

@ -63,8 +63,7 @@ endif
libnq_net_a_SOURCES= net_dgrm.c net_loop.c net_main.c net_vcr.c $(net_sources)
EXTRA_libnq_net_a_SOURCES= \
net_dos.c net_bw.c net_bsd.c net_ipx.c net_mp.c net_win.c net_wins.c \
net_wipx.c net_udp.c
net_bsd.c net_win.c net_wins.c net_udp.c
cl_plugin_LIBS= \
$(CLIENT_PLUGIN_STATIC_LIBS) \

View file

@ -1,795 +0,0 @@
/*
net_bw.c
@description@
Copyright (C) 1996-1997 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
static __attribute__ ((unused)) const char rcsid[] =
"$Id$";
#include <stdio.h>
#include <stdlib.h>
#include <dpmi.h>
#include "dosisms.h"
// this section is general Unix stuff that we need
#define EIO 5 /* I/O error */
#define EBADS 9
#define EWOULDBLOCK 35 /* function would block */
#define EMSGSIZE 40 /* message to big for buffers */
#define EPROTONOSUPPORT 43 /* Protocol not supported */
#define ESOCKTNOSUPPORT 44 /* Socket type not supported */
#define EPFNOSUPPORT 46 /* Protocol family not supported */
#define EAFNOSUPPORT 47 /* Address family not supported */
#define ECONNABORTED 53 /* User requested hangup */
#define ENOBUFS 55 /* No buffers available */
#define EISCONN 56 /* Socket has closed */
#define ENOTCONN 57 /* Socket is not connected */
#define ESHUTDOWN 58 /* Socket is closed */
#define ETOOMANYREFS 59 /* Too many sockets open */
#define ETIMEDOUT 60 /* Connection timed out */
#define ECONNREFUSED 61 /* Connection refused */
#define AF_INET 2 /* internet */
#define PF_INET AF_INET
#define SOCK_STREAM 1 /* stream */
#define SOCK_DGRAM 2 /* datagram */
#define IPPROTO_TCP 6
#define IPPROTO_UDP 17
#define INADDR_ANY 0
#define SIOCDONE 0x7300
#define FIONREAD 0x667f
#define FIONBIO 0x667e
#define FIONWIN 0x1000
#define FIONTIN 0x2000
#define BRDINIT 0
#define BRDADDR 10
#define MAXHOSTNAMELEN 256
#define SOL_SOCKET 0xffff /* options for socket level */
/*
* Option flags per-socket.
*/
#define SO_DEBUG 0x0001 /* turn on debugging info recording */
#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */
#define SO_REUSEADDR 0x0004 /* allow local address reuse */
#define SO_KEEPALIVE 0x0008 /* keep connections alive */
#define SO_DONTROUTE 0x0010 /* just use interface addresses */
#define SO_BROADCAST 0x0020 /* permit sending of broadcast msgs */
#define SO_USELOOPBACK 0x0040 /* bypass hardware when possible */
#define SO_LINGER 0x0080 /* linger on close if data present */
#define SO_OOBINLINE 0x0100 /* leave received OOB data in line */
#define SO_USEPRIV 0x4000 /* allocate from privileged port area
*/
#define SO_CANTSIG 0x8000 /* prevent SIGPIPE on SS_CANTSENDMORE
*/
/*
* Additional options, not kept in so_options.
*/
#define SO_SNDBUF 0x1001 /* send buffer size */
#define SO_RCVBUF 0x1002 /* receive buffer size */
#define SO_SNDLOWAT 0x1003 /* send low-water mark */
#define SO_RCVLOWAT 0x1004 /* receive low-water mark */
#define SO_SNDTIMEO 0x1005 /* send timeout */
#define SO_RCVTIMEO 0x1006 /* receive timeout */
#define SO_ERROR 0x1007 /* get error status and clear */
#define SO_TYPE 0x1008 /* get socket type */
struct in_addr {
union {
struct {
unsigned char s_b1, s_b2, s_b3, s_b4;
} S_un_b;
struct {
unsigned short s_w1, s_w2;
} S_un_w;
unsigned long S_addr;
} S_un;
};
#define s_addr S_un.S_addr /* can be used for most tcp & ip code
*/
#define s_host S_un.S_un_b.s_b2 /* host on imp */
#define s_net S_un.S_un_b.s_b1 /* network */
#define s_imp S_un.S_un_w.s_w2 /* imp */
#define s_impno S_un.S_un_b.s_b4 /* imp # */
#define s_lh S_un.S_un_b.s_b3 /* logical host */
struct sockaddr_in {
short sin_family;
unsigned short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
struct hostent {
char *h_name; /* official name of host */
char **h_aliases; /* alias list */
int h_addrtype; /* host address type */
int h_length; /* length of address */
char **h_addr_list; /* list of addresses from name server
*/
#define h_addr h_addr_list[0] /* address, for backward compatiblity
*/
};
char *inet_ntoa (struct in_addr in);
// this section is B&W specific constants & structures
#define BW_IOCTL_BIND 0
#define BW_IOCTL_CLEAROPTIONS 5
#define BW_IOCTL_SETOPTIONS 6
#define BW_IOCTL_PEEK 7
#define BW_IOCTL_SETWINMASK 8
#define BW_OPTION_BLOCKING 0x01
#define BW_OPTION_REUSEBUFFERS 0x80
#define BW_ERR_USR_HANGUP 50
#define BW_ERR_HANGUP 51
#define BW_ERR_NET_ERR 52
#define BW_ERR_IS_CLOSED 53
#define BW_ERR_TIME_OUT 54
#define BW_ERR_RESET 55
#define BW_ERR_FULL 56
#define BW_ERR_BLOCK 57
#define BW_ERR_SHUTDOWN 58
#pragma pack(1)
typedef struct {
char state; // always 1
short localPort;
struct in_addr localAddr;
char reason; // always 0
char options;
short dataAvailable;
} BW_UDPinfo_t;
typedef struct {
char reserved1[6];
unsigned short info2Offset;
char reserved2[18];
struct in_addr remoteAddr;
} BW_UDPreadInfo1_t;
typedef struct {
short remotePort;
char reserved1[2];
unsigned short dataLenPlus8;
char reserved2[2];
char data[1]; // actual size is <dataLenPlus8> - 8
//
} BW_UDPreadInfo2_t;
typedef struct {
char reserved1[2];
short remotePort;
unsigned short dataLen;
struct in_addr remoteAddr;
char reserved2[42];
char data[1]; // actual size is <datalen>
} BW_writeInfo_t;
typedef struct {
short ioport;
byte dma;
byte vector;
byte irq;
short bufferSize;
short maxWindow;
short timeZone;
byte myType;
int inetAddr;
short value;
byte subnetMask;
short etherPointer;
short logserverPointer;
short nameserverPointer;
short printserverPointer;
short timeserverPointer;
short gatewayPointer;
short driverSegment;
byte transferSize;
char cardName[9];
} BW_ethdevinfo_t;
#pragma pack()
#define LOWMEM_SIZE 4096
static unsigned char *lowmem_buffer;
static int lowmem_bufseg;
static int lowmem_bufoff;
static BW_ethdevinfo_t ethdevinfo;
static int netmask;
static struct in_addr bcastaddr;
static int net_acceptsocket = -1; // socket for fielding new
// connections
static int net_controlsocket = 0;
#include "net_bw.h"
//=============================================================================
static int
BW_ioctl (int s, char *msg, int msglen)
{
Q_memcpy (lowmem_buffer, msg, msglen);
regs.x.ax = 0x4403;
regs.x.bx = s;
regs.x.cx = msglen;
regs.x.dx = lowmem_bufoff;
regs.x.ds = lowmem_bufseg;
if (dos_int86 (0x21))
return regs.x.ax;
return 0;
}
//=============================================================================
static int
BW_TranslateError (int error)
{
switch (error) {
case BW_ERR_USR_HANGUP:
return ECONNABORTED;
case BW_ERR_HANGUP:
return EISCONN;
case BW_ERR_NET_ERR:
return ENOTCONN;
case BW_ERR_IS_CLOSED:
return ENOTCONN;
case BW_ERR_TIME_OUT:
return ETIMEDOUT;
case BW_ERR_RESET:
return ECONNREFUSED;
case BW_ERR_FULL:
return ETOOMANYREFS;
case BW_ERR_BLOCK:
return EWOULDBLOCK;
case BW_ERR_SHUTDOWN:
return ESHUTDOWN;
}
return EIO;
}
//=============================================================================
static int
GetEthdevinfo (void)
{
int fd;
Q_strcpy ((char *) lowmem_buffer, "ETHDEV27");
regs.x.ax = 0x3d42;
regs.x.ds = lowmem_bufseg;
regs.x.dx = lowmem_bufoff;
if (dos_int86 (0x21))
return -1;
fd = regs.x.ax;
regs.x.ax = 0x4401;
regs.x.bx = fd;
regs.x.dx = 0x60;
dos_int86 (0x21);
regs.h.ah = 0x3f;
regs.x.cx = sizeof (ethdevinfo);
regs.x.es = regs.x.ds = lowmem_bufseg;
regs.x.dx = lowmem_bufoff;
regs.x.bx = fd;
if (dos_int86 (0x21))
return -1;
Q_memcpy (&ethdevinfo, lowmem_buffer, regs.x.ax);
regs.h.ah = 0x3e;
regs.x.bx = fd;
dos_int86 (0x21);
return 0;
}
//=============================================================================
int
BW_Init (void)
{
struct qsockaddr addr;
char *colon;
if (COM_CheckParm ("-noudp"))
return -1;
lowmem_buffer = dos_getmemory (LOWMEM_SIZE);
if (!lowmem_buffer)
Sys_Error ("not enough low memory");
lowmem_bufoff = ptr2real (lowmem_buffer) & 0xf;
lowmem_bufseg = ptr2real (lowmem_buffer) >> 4;
if (GetEthdevinfo ()) {
Con_DPrintf ("Beame & Whiteside TCP/IP not detected\n");
dos_freememory (lowmem_buffer);
return -1;
}
netmask = 0xffffffff >> (32 - ethdevinfo.subnetMask);
bcastaddr.s_addr = (ethdevinfo.inetAddr & netmask) | (~netmask);
if ((net_controlsocket = BW_OpenSocket (0)) == -1) {
dos_freememory (lowmem_buffer);
Con_DPrintf ("BW_Init unable to open control socket; disabled\n");
return -1;
}
BW_GetSocketAddr (net_controlsocket, &addr);
Q_strcpy (my_tcpip_address, BW_AddrToString (&addr));
colon = Q_strrchr (my_tcpip_address, ':');
if (colon)
*colon = 0;
Con_Printf ("BW_Init: UDP initialized\n");
tcpipAvailable = true;
return net_controlsocket;
}
//=============================================================================
void
BW_Shutdown (void)
{
BW_Listen (false);
BW_CloseSocket (net_controlsocket);
dos_freememory (lowmem_buffer);
}
//=============================================================================
void
BW_Listen (qboolean state)
{
// enable listening
if (state) {
if (net_acceptsocket != -1)
return;
if ((net_acceptsocket = BW_OpenSocket (net_hostport)) == -1)
Sys_Error ("BW_Listen: Unable to open accept socket");
return;
}
// disable listening
if (net_acceptsocket == -1)
return;
BW_CloseSocket (net_acceptsocket);
net_acceptsocket = -1;
}
//=============================================================================
/*
OpenSocket returns a handle to a network socket that has been opened,
set to nonblocking, and bound to <port>. Additional socket options
should be set here if they are needed. -1 is returned on failure.
*/
int
BW_OpenSocket (int port)
{
int s;
int ret;
int deadman = 3 * 1024;
static int dynamic = 1024;
static char reuse_msg[2] = { BW_IOCTL_SETOPTIONS, BW_OPTION_REUSEBUFFERS };
static char bind_msg[3] = { BW_IOCTL_BIND, 0, 0 };
static char nonblock_msg[2] = { BW_IOCTL_CLEAROPTIONS, BW_OPTION_BLOCKING };
// allocate a UDP socket
Q_strcpy ((char *) lowmem_buffer, "UDP-IP10");
regs.x.ax = 0x3d42;
regs.x.ds = lowmem_bufseg;
regs.x.dx = lowmem_bufoff;
if (dos_int86 (0x21)) {
Con_Printf ("BW_OpenSocket failed: %u\n",
BW_TranslateError (regs.x.ax));
return -1;
}
s = regs.x.ax;
// set file descriptor to raw mode
regs.x.ax = 0x4401;
regs.x.bx = s;
regs.x.dx = 0x60;
dos_int86 (0x21);
if (BW_ioctl (s, reuse_msg, 2)) {
Con_Printf ("BW_OpenSocket ioctl(reuse) failed\n");
return -1;
}
if (BW_ioctl (s, nonblock_msg, 2)) {
Con_Printf ("BW_OpenSocket ioctl(nonblocking) failed\n");
return -1;
}
// if a socket was specified, bind to it and return
if (port) {
*(short *) &bind_msg[1] = port;
if (BW_ioctl (s, bind_msg, 3)) {
BW_CloseSocket (s);
return -1;
}
return s;
}
// B&W does NOT do dynamic allocation, so if port == 0 we must fake it
do {
port = dynamic++;
if (dynamic == 4096)
dynamic = 1024;
deadman--;
*(short *) &bind_msg[1] = port;
ret = BW_ioctl (s, bind_msg, 3);
}
while (ret && deadman);
if (ret)
return -1;
return s;
}
//=============================================================================
int
BW_CloseSocket (int socket)
{
regs.h.ah = 0x3e;
regs.x.bx = socket;
if (dos_int86 (0x21)) {
Con_Printf ("BW_CloseSocket %u failed: %u\n", socket,
BW_TranslateError (regs.x.ax));
return -1;
}
return 0;
}
//=============================================================================
int
BW_Connect (int socket, struct qsockaddr *hostaddr)
{
return 0;
}
//=============================================================================
int
BW_CheckNewConnections (void)
{
if (net_acceptsocket == 0)
return -1;
// see if there's anything waiting
regs.x.ax = 0x4406;
regs.x.bx = net_acceptsocket;
dos_int86 (0x21);
if (regs.x.ax == 0)
return -1;
return net_acceptsocket;
}
//=============================================================================
int
BW_Read (int s, byte * buf, int len, struct qsockaddr *from)
{
BW_UDPreadInfo1_t *info1;
BW_UDPreadInfo2_t *info2;
// ask if there's anything waiting
regs.x.ax = 0x4406;
regs.x.bx = s;
dos_int86 (0x21);
if (regs.x.ax == 0)
return 0;
// there was, so let's get it
regs.h.ah = 0x3f;
regs.x.cx = /* len + 53 */ LOWMEM_SIZE;
regs.x.es = regs.x.ds = lowmem_bufseg;
regs.x.dx = lowmem_bufoff;
regs.x.bx = s;
if (dos_int86 (0x21)) {
Con_Printf ("BW UDP read error: %u\n", BW_TranslateError (regs.x.ax));
return -1;
}
info1 = (BW_UDPreadInfo1_t *) lowmem_buffer;
info2 = (BW_UDPreadInfo2_t *) (lowmem_buffer + info1->info2Offset);
if (from) {
from->sa_family = AF_INET;
((struct sockaddr_in *) from)->sin_addr = info1->remoteAddr;
((struct sockaddr_in *) from)->sin_port = htons (info2->remotePort);
}
len = info2->dataLenPlus8 - 8;
if (len > NET_DATAGRAMSIZE) {
Con_Printf ("BW UDP read packet too large: %u\n", len);
return -1;
}
Q_memcpy (buf, info2->data, len);
return len;
}
//=============================================================================
int
BW_Broadcast (int s, byte * msg, int len)
{
BW_writeInfo_t *writeInfo;
// ask if we're clear to send
regs.x.ax = 0x4407;
regs.x.bx = s;
dos_int86 (0x21);
if (regs.x.ax == 0)
return 0;
// yes, let's do it
writeInfo = (BW_writeInfo_t *) lowmem_buffer;
writeInfo->remoteAddr = bcastaddr;
writeInfo->remotePort = net_hostport;
writeInfo->dataLen = len;
if (len > NET_DATAGRAMSIZE)
Sys_Error ("BW UDP write packet too large: %u", len);
Q_memcpy (writeInfo->data, msg, len);
writeInfo->data[len] = 0;
regs.h.ah = 0x40;
regs.x.bx = s;
regs.x.cx = len + sizeof (BW_writeInfo_t);
regs.x.es = regs.x.ds = lowmem_bufseg;
regs.x.dx = lowmem_bufoff;
if (dos_int86 (0x21)) {
Con_Printf ("BW_Broadcast failed: %u\n", BW_TranslateError (regs.x.ax));
return -1;
}
return len;
}
//=============================================================================
int
BW_Write (int s, byte * msg, int len, struct qsockaddr *to)
{
BW_writeInfo_t *writeInfo;
// ask if we're clear to send
regs.x.ax = 0x4407;
regs.x.bx = s;
dos_int86 (0x21);
if (regs.x.ax == 0)
return 0;
// yes, let's do it
writeInfo = (BW_writeInfo_t *) lowmem_buffer;
writeInfo->remoteAddr = ((struct sockaddr_in *) to)->sin_addr;
writeInfo->remotePort = ntohs (((struct sockaddr_in *) to)->sin_port);
writeInfo->dataLen = len;
if (len > NET_DATAGRAMSIZE)
Sys_Error ("BW UDP write packet too large: %u", len);
Q_memcpy (writeInfo->data, msg, len);
writeInfo->data[len] = 0;
regs.h.ah = 0x40;
regs.x.bx = s;
regs.x.cx = len + sizeof (BW_writeInfo_t);
regs.x.es = regs.x.ds = lowmem_bufseg;
regs.x.dx = lowmem_bufoff;
if (dos_int86 (0x21)) {
Con_Printf ("BW_Write failed: %u\n", BW_TranslateError (regs.x.ax));
return -1;
}
return len;
}
//=============================================================================
char *
BW_AddrToString (struct qsockaddr *addr)
{
static char buffer[22];
snprintf (buffer, sizeof (buffer), "%d.%d.%d.%d:%d",
((struct sockaddr_in *) addr)->sin_addr.s_net,
((struct sockaddr_in *) addr)->sin_addr.s_host,
((struct sockaddr_in *) addr)->sin_addr.s_lh,
((struct sockaddr_in *) addr)->sin_addr.s_impno,
ntohs (((struct sockaddr_in *) addr)->sin_port)
);
return buffer;
}
//=============================================================================
int
BW_StringToAddr (char *string, struct qsockaddr *addr)
{
int ha1, ha2, ha3, ha4, hp;
int ipaddr;
sscanf (string, "%d.%d.%d.%d:%d", &ha1, &ha2, &ha3, &ha4, &hp);
ipaddr = (ha1 << 24) | (ha2 << 16) | (ha3 << 8) | ha4;
addr->sa_family = AF_INET;
((struct sockaddr_in *) addr)->sin_addr.s_addr = htonl (ipaddr);
((struct sockaddr_in *) addr)->sin_port = htons ((short) hp);
return 0;
}
//=============================================================================
int
BW_GetSocketAddr (int socket, struct qsockaddr *addr)
{
regs.x.ax = 0x4402;
regs.x.bx = socket;
regs.x.cx = sizeof (BW_UDPinfo_t);
regs.x.dx = lowmem_bufoff;
regs.x.ds = lowmem_bufseg;
dos_int86 (0x21);
addr->sa_family = AF_INET;
((struct sockaddr_in *) addr)->sin_addr.s_addr =
((BW_UDPinfo_t *) lowmem_buffer)->localAddr.s_addr;
((struct sockaddr_in *) addr)->sin_port =
htons (((BW_UDPinfo_t *) lowmem_buffer)->localPort);
return 0;
}
//=============================================================================
int
BW_GetNameFromAddr (struct qsockaddr *addr, char *name)
{
Q_strcpy (name, BW_AddrToString (addr));
return 0;
}
///=============================================================================
int
BW_GetAddrFromName (char *name, struct qsockaddr *hostaddr)
{
char buff[MAXHOSTNAMELEN];
char *b;
int addr;
int num;
int mask;
int run;
int port;
if (name[0] < '0' || name[0] > '9')
return -1;
buff[0] = '.';
b = buff;
Q_strcpy (buff + 1, name);
if (buff[1] == '.')
b++;
addr = 0;
mask = -1;
while (*b == '.') {
b++;
num = 0;
run = 0;
while (!(*b < '0' || *b > '9')) {
num = num * 10 + *b++ - '0';
if (++run > 3)
return -1;
}
if ((*b < '0' || *b > '9') && *b != '.' && *b != ':' && *b != 0)
return -1;
if (num < 0 || num > 255)
return -1;
mask <<= 8;
addr = (addr << 8) + num;
}
addr = htonl (addr);
mask = htonl (mask);
if (*b++ == ':')
port = Q_atoi (b);
else
port = net_hostport;
hostaddr->sa_family = AF_INET;
((struct sockaddr_in *) hostaddr)->sin_port = htons ((short) port);
((struct sockaddr_in *) hostaddr)->sin_addr.s_addr =
((ethdevinfo.inetAddr & mask) | addr);
return 0;
}
//=============================================================================
int
BW_AddrCompare (struct qsockaddr *addr1, struct qsockaddr *addr2)
{
if (addr1->sa_family != addr2->sa_family)
return -1;
if (((struct sockaddr_in *) addr1)->sin_addr.s_addr !=
((struct sockaddr_in *) addr2)->sin_addr.s_addr)
return -1;
if (((struct sockaddr_in *) addr1)->sin_port !=
((struct sockaddr_in *) addr2)->sin_port)
return 1;
return 0;
}
//=============================================================================
int
BW_GetSocketPort (struct qsockaddr *addr)
{
return ntohs (((struct sockaddr_in *) addr)->sin_port);
}
int
BW_SetSocketPort (struct qsockaddr *addr, int port)
{
((struct sockaddr_in *) addr)->sin_port = htons (port);
return 0;
}
//=============================================================================

View file

@ -1,166 +0,0 @@
/*
net_dos.c
@description@
Copyright (C) 1996-1997 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
static __attribute__ ((unused)) const char rcsid[] =
"$Id$";
#include "net_loop.h"
#include "net_dgrm.h"
#include "net_ser.h"
net_driver_t net_drivers[MAX_NET_DRIVERS] = {
{
"Loopback",
false,
Loop_Init,
Loop_Listen,
Loop_SearchForHosts,
Loop_Connect,
Loop_CheckNewConnections,
Loop_GetMessage,
Loop_SendMessage,
Loop_SendUnreliableMessage,
Loop_CanSendMessage,
Loop_CanSendUnreliableMessage,
Loop_Close,
Loop_Shutdown}
,
{
"Datagram",
false,
Datagram_Init,
Datagram_Listen,
Datagram_SearchForHosts,
Datagram_Connect,
Datagram_CheckNewConnections,
Datagram_GetMessage,
Datagram_SendMessage,
Datagram_SendUnreliableMessage,
Datagram_CanSendMessage,
Datagram_CanSendUnreliableMessage,
Datagram_Close,
Datagram_Shutdown}
,
{
"Serial",
false,
Serial_Init,
Serial_Listen,
Serial_SearchForHosts,
Serial_Connect,
Serial_CheckNewConnections,
Serial_GetMessage,
Serial_SendMessage,
Serial_SendUnreliableMessage,
Serial_CanSendMessage,
Serial_CanSendUnreliableMessage,
Serial_Close,
Serial_Shutdown}
};
int net_numdrivers = 3;
#include "net_bw.h"
#include "net_ipx.h"
#include "net_mp.h"
net_landriver_t net_landrivers[MAX_NET_DRIVERS] = {
{
"Beame & Whiteside TCP/IP",
false,
0,
BW_Init,
BW_Shutdown,
BW_Listen,
BW_OpenSocket,
BW_CloseSocket,
BW_Connect,
BW_CheckNewConnections,
BW_Read,
BW_Write,
BW_Broadcast,
BW_AddrToString,
BW_StringToAddr,
BW_GetSocketAddr,
BW_GetNameFromAddr,
BW_GetAddrFromName,
BW_AddrCompare,
BW_GetSocketPort,
BW_SetSocketPort}
,
{
"IPX",
false,
0,
IPX_Init,
IPX_Shutdown,
IPX_Listen,
IPX_OpenSocket,
IPX_CloseSocket,
IPX_Connect,
IPX_CheckNewConnections,
IPX_Read,
IPX_Write,
IPX_Broadcast,
IPX_AddrToString,
IPX_StringToAddr,
IPX_GetSocketAddr,
IPX_GetNameFromAddr,
IPX_GetAddrFromName,
IPX_AddrCompare,
IPX_GetSocketPort,
IPX_SetSocketPort}
,
{
"Win95 TCP/IP",
false,
0,
MPATH_Init,
MPATH_Shutdown,
MPATH_Listen,
MPATH_OpenSocket,
MPATH_CloseSocket,
MPATH_Connect,
MPATH_CheckNewConnections,
MPATH_Read,
MPATH_Write,
MPATH_Broadcast,
MPATH_AddrToString,
MPATH_StringToAddr,
MPATH_GetSocketAddr,
MPATH_GetNameFromAddr,
MPATH_GetAddrFromName,
MPATH_AddrCompare,
MPATH_GetSocketPort,
MPATH_SetSocketPort}
};
int net_numlandrivers = 3;

View file

@ -1,736 +0,0 @@
/*
net_ipx.c
@description@
Copyright (C) 1996-1997 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
static __attribute__ ((unused)) const char rcsid[] =
"$Id$";
#include <stdio.h>
#include <stdlib.h>
#include <dpmi.h>
#include "dosisms.h"
#include "net_ipx.h"
#define EIO 5 /* I/O error */
#define AF_NETWARE 64
#define IPX_OPEN 0
#define IPX_CLOSE 1
#define IPX_GETROUTE 2
#define IPX_SEND 3
#define IPX_LISTEN 4
#define IPX_SCHEDULEEVENT 5
#define IPX_CANCEL 6
#define IPX_SCHEDULESPECIALEVENT 7
#define IPX_GETINTERVALMARKER 8
#define IPX_GETADDRESS 9
#define IPX_RELINQUISH 10
#define PTYPE_UNKNOWN 0
#define PTYPE_RIP 1
#define PTYPE_ECHO 2
#define PTYPE_ERROR 3
#define PTYPE_IPX 4
#define PTYPE_SPX 5
#pragma pack(1)
typedef struct {
byte network[4];
byte node[6];
short socket;
} IPXaddr;
struct sockaddr_ipx {
short sipx_family;
IPXaddr sipx_addr;
char sipx_zero[2];
};
#define sipx_port sipx_addr.socket
typedef struct {
short checkSum;
short length;
byte transportControl;
byte type;
IPXaddr destination;
IPXaddr source;
} IPXheader;
typedef struct ECBStructure {
struct ECBStructure *link;
unsigned short ESR_off;
unsigned short ESR_seg;
byte inUse;
byte completionCode;
short socket;
byte IPXWorkspace[4];
byte driverWorkspace[12];
byte immediateAddress[6];
short fragCount;
short fragOff;
short fragSeg;
short fragSize;
} ECB;
#pragma pack()
typedef struct {
ECB ecb;
IPXheader header;
int sequence;
char data[NET_DATAGRAMSIZE];
} ipx_lowmem_buffer_t;
#define LOWMEMSIZE (100 * 1024)
#define LOWMEMSAVE 256
#define IPXBUFFERS ((LOWMEMSIZE - LOWMEMSAVE)/ sizeof(ipx_lowmem_buffer_t))
#define IPXSOCKBUFFERS 5
#define IPXSOCKETS (IPXBUFFERS / IPXSOCKBUFFERS)
// each socket's socketbuffer 0 is used for sending, the others for listening
typedef struct {
char reserved[LOWMEMSAVE];
ipx_lowmem_buffer_t socketbuffer[IPXSOCKETS][IPXSOCKBUFFERS];
} ipx_lowmem_area_t;
static int ipxsocket[IPXSOCKETS];
static ECB *readlist[IPXSOCKETS];
static int sequence[IPXSOCKETS];
static int handlesInUse;
static ipx_lowmem_area_t *lma;
static char *lowmem_buffer;
static int lowmem_bufseg;
static int lowmem_bufoff;
static unsigned short ipx_cs;
static unsigned short ipx_ip;
static int net_acceptsocket = -1;
static int net_controlsocket;
static void IPX_PollProcedure (void);
static PollProcedure pollProcedure = { NULL, 0.0, IPX_PollProcedure };
//=============================================================================
static void
IPX_GetLocalAddress (IPXaddr * addr)
{
regs.x.cs = ipx_cs;
regs.x.ip = ipx_ip;
regs.x.bx = IPX_GETADDRESS;
regs.x.es = lowmem_bufseg;
regs.x.si = lowmem_bufoff;
__dpmi_simulate_real_mode_procedure_retf ((__dpmi_regs *) & regs);
Q_memcpy (addr, lowmem_buffer, 10);
}
//=============================================================================
static int
IPX_GetLocalTarget (IPXaddr * addr, byte * localTarget)
{
regs.x.cs = ipx_cs;
regs.x.ip = ipx_ip;
regs.x.bx = IPX_GETROUTE;
regs.x.es = lowmem_bufseg;
regs.x.si = lowmem_bufoff;
regs.x.di = lowmem_bufoff + sizeof (IPXaddr);
Q_memcpy (lowmem_buffer, addr, sizeof (IPXaddr));
__dpmi_simulate_real_mode_procedure_retf ((__dpmi_regs *) & regs);
if (regs.h.al)
return -1;
Q_memcpy (localTarget, lowmem_buffer + sizeof (IPXaddr), 6);
return 0;
}
//=============================================================================
static void
IPX_ListenForPacket (ECB * ecb)
{
regs.x.cs = ipx_cs;
regs.x.ip = ipx_ip;
regs.x.bx = IPX_LISTEN;
regs.x.es = ptr2real (ecb) >> 4;
regs.x.si = ptr2real (ecb) & 0xf;
__dpmi_simulate_real_mode_procedure_retf ((__dpmi_regs *) & regs);
}
//=============================================================================
static void
IPX_RelinquishControl (void)
{
regs.x.cs = ipx_cs;
regs.x.ip = ipx_ip;
regs.x.bx = IPX_RELINQUISH;
__dpmi_simulate_real_mode_procedure_retf ((__dpmi_regs *) & regs);
}
void
IPX_PollProcedure (void)
{
IPX_RelinquishControl ();
SchedulePollProcedure (&pollProcedure, 0.01);
}
//=============================================================================
static void
ProcessReadyList (int s)
{
int n;
ECB *ecb;
ECB *prev;
for (n = 1; n < IPXSOCKBUFFERS; n++) {
if (lma->socketbuffer[s][n].ecb.inUse == 0) {
for (ecb = readlist[s], prev = NULL; ecb; ecb = ecb->link) {
if (lma->socketbuffer[s][n].sequence <
((ipx_lowmem_buffer_t *) ecb)->sequence)
break;
prev = ecb;
}
if (ecb)
lma->socketbuffer[s][n].ecb.link = ecb;
else
lma->socketbuffer[s][n].ecb.link = NULL;
if (prev)
prev->link = &lma->socketbuffer[s][n].ecb;
else
readlist[s] = &lma->socketbuffer[s][n].ecb;
lma->socketbuffer[s][n].ecb.inUse = 0xff;
}
}
}
//=============================================================================
int
IPX_Init (void)
{
int s;
int n;
struct qsockaddr addr;
char *colon;
if (COM_CheckParm ("-noipx"))
return -1;
// find the IPX far call entry point
regs.x.ax = 0x7a00;
__dpmi_simulate_real_mode_interrupt (0x2f, (__dpmi_regs *) & regs);
if (regs.h.al != 0xff) {
Con_Printf ("IPX not detected\n");
return -1;
}
ipx_cs = regs.x.es;
ipx_ip = regs.x.di;
// grab a chunk of memory down in DOS land
lowmem_buffer = dos_getmemory (LOWMEMSIZE);
if (!lowmem_buffer) {
Con_Printf ("IPX_Init: Not enough low memory\n");
return -1;
}
lowmem_bufoff = ptr2real (lowmem_buffer) & 0xf;
lowmem_bufseg = ptr2real (lowmem_buffer) >> 4;
// init socket handles & buffers
handlesInUse = 0;
lma = (ipx_lowmem_area_t *) lowmem_buffer;
for (s = 0; s < IPXSOCKETS; s++) {
ipxsocket[s] = 0;
for (n = 0; n < IPXSOCKBUFFERS; n++) {
lma->socketbuffer[s][n].ecb.link = NULL;
lma->socketbuffer[s][n].ecb.ESR_off = 0;
lma->socketbuffer[s][n].ecb.ESR_seg = 0;
lma->socketbuffer[s][n].ecb.socket = 0;
lma->socketbuffer[s][n].ecb.inUse = 0xff;
lma->socketbuffer[s][n].ecb.completionCode = 0;
lma->socketbuffer[s][n].ecb.fragCount = 1;
lma->socketbuffer[s][n].ecb.fragOff =
ptr2real (&lma->socketbuffer[s][n].header) & 0xf;
lma->socketbuffer[s][n].ecb.fragSeg =
ptr2real (&lma->socketbuffer[s][n].header) >> 4;
lma->socketbuffer[s][n].ecb.fragSize =
sizeof (IPXheader) + sizeof (int) + NET_DATAGRAMSIZE;
}
}
if ((net_controlsocket = IPX_OpenSocket (0)) == -1) {
dos_freememory (lowmem_buffer);
Con_DPrintf ("IPX_Init: Unable to open control socket\n");
return -1;
}
SchedulePollProcedure (&pollProcedure, 0.01);
IPX_GetSocketAddr (net_controlsocket, &addr);
Q_strcpy (my_ipx_address, IPX_AddrToString (&addr));
colon = Q_strrchr (my_ipx_address, ':');
if (colon)
*colon = 0;
Con_Printf ("IPX initialized\n");
ipxAvailable = true;
return net_controlsocket;
}
//=============================================================================
void
IPX_Shutdown (void)
{
IPX_Listen (false);
IPX_CloseSocket (net_controlsocket);
dos_freememory (lowmem_buffer);
}
//=============================================================================
void
IPX_Listen (qboolean state)
{
// enable listening
if (state) {
if (net_acceptsocket != -1)
return;
if ((net_acceptsocket = IPX_OpenSocket (net_hostport)) == -1)
Sys_Error ("IPX_Listen: Unable to open accept socket");
return;
}
// disable listening
if (net_acceptsocket == -1)
return;
IPX_CloseSocket (net_acceptsocket);
net_acceptsocket = -1;
}
//=============================================================================
int
IPX_OpenSocket (int port)
{
int handle;
int n;
unsigned short socket;
if (handlesInUse == IPXSOCKETS)
return -1;
// open the IPX socket
regs.x.cs = ipx_cs;
regs.x.ip = ipx_ip;
regs.x.bx = IPX_OPEN;
regs.h.al = 0;
regs.x.dx = htons (port);
__dpmi_simulate_real_mode_procedure_retf ((__dpmi_regs *) & regs);
if (regs.h.al == 0xfe) {
Con_DPrintf ("IPX_OpenSocket: all sockets in use\n");
return -1;
}
if (regs.h.al == 0xff) {
Con_DPrintf ("IPX_OpenSocket: socket already open\n");
return -1;
}
if (regs.h.al != 0) {
Con_DPrintf ("IPX_OpenSocket: error %02x\n", regs.h.al);
return -1;
}
socket = regs.x.dx;
// grab a handle; fill in the ECBs, and get them listening
for (handle = 0; handle < IPXSOCKETS; handle++) {
if (ipxsocket[handle] == 0) {
ipxsocket[handle] = socket;
readlist[handle] = NULL;
sequence[handle] = 0;
for (n = 0; n < IPXSOCKBUFFERS; n++) {
lma->socketbuffer[handle][n].ecb.socket = socket;
lma->socketbuffer[handle][n].ecb.inUse = 0;
if (n)
IPX_ListenForPacket (&lma->socketbuffer[handle][n].ecb);
}
handlesInUse++;
return handle;
}
}
// "this will NEVER happen"
Sys_Error ("IPX_OpenSocket: handle allocation failed");
return -1;
}
//=============================================================================
int
IPX_CloseSocket (int handle)
{
// if there's a send in progress, give it one last chance
if (lma->socketbuffer[handle][0].ecb.inUse != 0)
IPX_RelinquishControl ();
// close the socket (all pending sends/received are cancelled)
regs.x.cs = ipx_cs;
regs.x.ip = ipx_ip;
regs.x.bx = IPX_CLOSE;
regs.x.dx = ipxsocket[handle];
__dpmi_simulate_real_mode_procedure_retf ((__dpmi_regs *) & regs);
ipxsocket[handle] = 0;
handlesInUse--;
return 0;
}
//=============================================================================
int
IPX_Connect (int handle, struct qsockaddr *addr)
{
IPXaddr ipxaddr;
Q_memcpy (&ipxaddr, &((struct sockaddr_ipx *) addr)->sipx_addr,
sizeof (IPXaddr));
if (IPX_GetLocalTarget
(&ipxaddr, lma->socketbuffer[handle][0].ecb.immediateAddress) != 0) {
Con_Printf ("Get Local Target failed\n");
return -1;
}
return 0;
}
//=============================================================================
int
IPX_CheckNewConnections (void)
{
int n;
if (net_acceptsocket == -1)
return -1;
for (n = 1; n < IPXSOCKBUFFERS; n++)
if (lma->socketbuffer[net_acceptsocket][n].ecb.inUse == 0)
return net_acceptsocket;
return -1;
}
//=============================================================================
int
IPX_Read (int handle, byte * buf, int len, struct qsockaddr *addr)
{
ECB *ecb;
ipx_lowmem_buffer_t *rcvbuf;
int copylen;
ProcessReadyList (handle);
tryagain:
if (readlist[handle] == NULL)
return 0;
ecb = readlist[handle];
readlist[handle] = ecb->link;
if (ecb->completionCode != 0) {
Con_Printf ("Warning: IPX_Read error %02x\n", ecb->completionCode);
ecb->fragSize = sizeof (IPXheader) + sizeof (int) + NET_DATAGRAMSIZE;
IPX_ListenForPacket (ecb);
goto tryagain;
}
rcvbuf = (ipx_lowmem_buffer_t *) ecb;
// copy the data up to the buffer
copylen =
ntohs (rcvbuf->header.length) - (sizeof (int) + sizeof (IPXheader));
if (len < copylen)
Sys_Error ("IPX_Read: buffer too small (%d vs %d)", len, copylen);
Q_memcpy (buf, rcvbuf->data, copylen);
// fill in the addr if they want it
if (addr) {
((struct sockaddr_ipx *) addr)->sipx_family = AF_NETWARE;
Q_memcpy (&((struct sockaddr_ipx *) addr)->sipx_addr,
rcvbuf->header.source.network, sizeof (IPXaddr));
((struct sockaddr_ipx *) addr)->sipx_zero[0] = 0;
((struct sockaddr_ipx *) addr)->sipx_zero[1] = 0;
}
// update the send ecb's immediate address
Q_memcpy (lma->socketbuffer[handle][0].ecb.immediateAddress,
rcvbuf->ecb.immediateAddress, 6);
// get this ecb listening again
rcvbuf->ecb.fragSize = sizeof (IPXheader) + sizeof (int) + NET_DATAGRAMSIZE;
IPX_ListenForPacket (&rcvbuf->ecb);
return copylen;
}
//=============================================================================
int
IPX_Broadcast (int handle, byte * buf, int len)
{
struct sockaddr_ipx addr;
int ret;
Q_memset (addr.sipx_addr.network, 0x00, 4);
Q_memset (addr.sipx_addr.node, 0xff, 6);
addr.sipx_port = htons (net_hostport);
Q_memset (lma->socketbuffer[handle][0].ecb.immediateAddress, 0xff, 6);
ret = IPX_Write (handle, buf, len, (struct qsockaddr *) &addr);
return ret;
}
//=============================================================================
int
IPX_Write (int handle, byte * buf, int len, struct qsockaddr *addr)
{
// has the previous send completed?
while (lma->socketbuffer[handle][0].ecb.inUse != 0)
IPX_RelinquishControl ();
switch (lma->socketbuffer[handle][0].ecb.completionCode) {
case 0x00: // success
case 0xfc: // request cancelled
break;
case 0xfd: // malformed packet
default:
Con_Printf ("IPX driver send failure: %02x\n",
lma->socketbuffer[handle][0].ecb.completionCode);
break;
case 0xfe: // packet undeliverable
case 0xff: // unable to send packet
Con_Printf ("IPX lost route, trying to re-establish\n");
// look for a new route
if (IPX_GetLocalTarget
(&lma->socketbuffer[handle][0].header.destination,
lma->socketbuffer[handle][0].ecb.immediateAddress) != 0)
return -1;
// re-send the one that failed
regs.x.cs = ipx_cs;
regs.x.ip = ipx_ip;
regs.x.bx = IPX_SEND;
regs.x.es = ptr2real (&lma->socketbuffer[handle][0].ecb) >> 4;
regs.x.si = ptr2real (&lma->socketbuffer[handle][0].ecb) & 0xf;
__dpmi_simulate_real_mode_procedure_retf ((__dpmi_regs *) & regs);
// report that we did not send the current one
return 0;
}
// ecb : length
lma->socketbuffer[handle][0].ecb.fragSize =
sizeof (IPXheader) + sizeof (int) + len;
// ipx header : type
lma->socketbuffer[handle][0].header.type = PTYPE_IPX;
// ipx header : destination
Q_memcpy (&lma->socketbuffer[handle][0].header.destination,
&((struct sockaddr_ipx *) addr)->sipx_addr, sizeof (IPXaddr));
// sequence number
lma->socketbuffer[handle][0].sequence = sequence[handle];
sequence[handle]++;
// copy down the data
Q_memcpy (lma->socketbuffer[handle][0].data, buf, len);
regs.x.cs = ipx_cs;
regs.x.ip = ipx_ip;
regs.x.bx = IPX_SEND;
regs.x.es = ptr2real (&lma->socketbuffer[handle][0].ecb) >> 4;
regs.x.si = ptr2real (&lma->socketbuffer[handle][0].ecb) & 0xf;
__dpmi_simulate_real_mode_procedure_retf ((__dpmi_regs *) & regs);
return len;
}
//=============================================================================
char *
IPX_AddrToString (struct qsockaddr *addr)
{
static char buf[28];
snprintf (buf, sizeof (buf), "%02x%02x%02x%02x:%02x%02x%02x%02x%02x%02x:%u",
((struct sockaddr_ipx *) addr)->sipx_addr.network[0],
((struct sockaddr_ipx *) addr)->sipx_addr.network[1],
((struct sockaddr_ipx *) addr)->sipx_addr.network[2],
((struct sockaddr_ipx *) addr)->sipx_addr.network[3],
((struct sockaddr_ipx *) addr)->sipx_addr.node[0],
((struct sockaddr_ipx *) addr)->sipx_addr.node[1],
((struct sockaddr_ipx *) addr)->sipx_addr.node[2],
((struct sockaddr_ipx *) addr)->sipx_addr.node[3],
((struct sockaddr_ipx *) addr)->sipx_addr.node[4],
((struct sockaddr_ipx *) addr)->sipx_addr.node[5],
ntohs (((struct sockaddr_ipx *) addr)->sipx_port)
);
return buf;
}
//=============================================================================
int
IPX_StringToAddr (char *string, struct qsockaddr *addr)
{
int val;
char buf[3];
buf[2] = 0;
Q_memset (addr, 0, sizeof (struct qsockaddr));
addr->sa_family = AF_NETWARE;
#define DO(src,dest) \
buf[0] = string[src]; \
buf[1] = string[src + 1]; \
if (sscanf (buf, "%x", &val) != 1) \
return -1; \
((struct sockaddr_ipx *)addr)->sipx_addr.dest = val
DO (0, network[0]);
DO (2, network[1]);
DO (4, network[2]);
DO (6, network[3]);
DO (9, node[0]);
DO (11, node[1]);
DO (13, node[2]);
DO (15, node[3]);
DO (17, node[4]);
DO (19, node[5]);
#undef DO
sscanf (&string[22], "%u", &val);
((struct sockaddr_ipx *) addr)->sipx_port = htons (val);
return 0;
}
//=============================================================================
int
IPX_GetSocketAddr (int handle, struct qsockaddr *addr)
{
Q_memset (addr, 0, sizeof (struct qsockaddr));
addr->sa_family = AF_NETWARE;
IPX_GetLocalAddress (&((struct sockaddr_ipx *) addr)->sipx_addr);
((struct sockaddr_ipx *) addr)->sipx_port = ipxsocket[handle];
return 0;
}
//=============================================================================
int
IPX_GetNameFromAddr (struct qsockaddr *addr, char *name)
{
Q_strcpy (name, IPX_AddrToString (addr));
return 0;
}
//=============================================================================
int
IPX_GetAddrFromName (char *name, struct qsockaddr *addr)
{
int n;
char buf[32];
n = Q_strlen (name);
if (n == 12) {
snprintf (buf, sizeof (buf), "00000000:%s:%u", name, net_hostport);
return IPX_StringToAddr (buf, addr);
}
if (n == 21) {
snprintf (buf, sizeof (buf), "%s:%u", name, net_hostport);
return IPX_StringToAddr (buf, addr);
}
if (n > 21 && n <= 27)
return IPX_StringToAddr (name, addr);
return -1;
}
//=============================================================================
int
IPX_AddrCompare (struct qsockaddr *addr1, struct qsockaddr *addr2)
{
if (addr1->sa_family != addr2->sa_family)
return -1;
if (Q_memcmp
(&((struct sockaddr_ipx *) addr1)->sipx_addr,
&((struct sockaddr_ipx *) addr2)->sipx_addr, 10))
return -1;
if (((struct sockaddr_ipx *) addr1)->sipx_port !=
((struct sockaddr_ipx *) addr2)->sipx_port)
return 1;
return 0;
}
//=============================================================================
int
IPX_GetSocketPort (struct qsockaddr *addr)
{
return ntohs (((struct sockaddr_ipx *) addr)->sipx_port);
}
int
IPX_SetSocketPort (struct qsockaddr *addr, int port)
{
((struct sockaddr_ipx *) addr)->sipx_port = htons (port);
return 0;
}
//=============================================================================

View file

@ -1,480 +0,0 @@
/*
net_mp.c
@description@
Copyright (C) 1996-1997 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
static __attribute__ ((unused)) const char rcsid[] =
"$Id$";
#include <dpmi.h>
#include "mpdosock.h"
short flat_selector;
int WSAGetLastError (void);
void sockets_flush (void);
#define MAXHOSTNAMELEN 256
static int net_acceptsocket = -1; // socket for fielding new
// connections
static int net_controlsocket;
static int net_broadcastsocket = 0;
//static qboolean ifbcastinit = false;
static struct qsockaddr broadcastaddr;
static unsigned long myAddr;
#include "net_mp.h"
//=============================================================================
int
MPATH_Init (void)
{
int i;
struct hostent *local = NULL;
char buff[MAXHOSTNAMELEN];
struct qsockaddr addr;
char *p;
if (COM_CheckParm ("-mpath") == 0)
return -1;
flat_selector = __dpmi_allocate_ldt_descriptors (1);
if (flat_selector == -1) {
Con_Printf ("MPATH_Init: Can't get flat selector\n");
return -1;
}
if (__dpmi_set_segment_base_address (flat_selector, 0) == -1) {
Con_Printf ("MPATH_Init: Can't seg flat base!\n");
return -1;
}
if (__dpmi_set_segment_limit (flat_selector, 0xffffffff) == -1) {
Con_Printf ("MPATH_Init: Can't set segment limit\n");
return -1;
}
// determine my name & address
if (gethostname (buff, MAXHOSTNAMELEN) == 0)
local = gethostbyname (buff);
if (local) {
myAddr = *(int *) local->h_addr_list[0];
// if the quake hostname isn't set, set it to the machine name
if (Q_strcmp (hostname->string, "UNNAMED") == 0) {
// see if it's a text IP address (well, close enough)
for (p = buff; *p; p++)
if ((*p < '0' || *p > '9') && *p != '.')
break;
// if it is a real name, strip off the domain; we only want the
// host
if (*p) {
for (i = 0; i < 15; i++)
if (buff[i] == '.')
break;
buff[i] = 0;
}
Cvar_Set (hostname, buff);
}
}
if ((net_controlsocket = MPATH_OpenSocket (0)) == -1)
Sys_Error ("MPATH_Init: Unable to open control socket");
((struct sockaddr_in *) &broadcastaddr)->sin_family = AF_INET;
((struct sockaddr_in *) &broadcastaddr)->sin_addr.s_addr = INADDR_BROADCAST;
((struct sockaddr_in *) &broadcastaddr)->sin_port = htons (net_hostport);
MPATH_GetSocketAddr (net_controlsocket, &addr);
Q_strcpy (my_tcpip_address, MPATH_AddrToString (&addr));
p = Q_strrchr (my_tcpip_address, ':');
if (p)
*p = 0;
Con_Printf ("MPath Initialized\n");
tcpipAvailable = true;
return net_controlsocket;
}
//=============================================================================
void
MPATH_Shutdown (void)
{
MPATH_Listen (false);
MPATH_CloseSocket (net_controlsocket);
}
//=============================================================================
void
MPATH_Listen (qboolean state)
{
// enable listening
if (state) {
if (net_acceptsocket != -1)
return;
if ((net_acceptsocket = MPATH_OpenSocket (net_hostport)) == -1)
Sys_Error ("MPATH_Listen: Unable to open accept socket");
return;
}
// disable listening
if (net_acceptsocket == -1)
return;
MPATH_CloseSocket (net_acceptsocket);
net_acceptsocket = -1;
}
//=============================================================================
int
MPATH_OpenSocket (int port)
{
int newsocket;
struct sockaddr_in address;
u_long _true = 1;
if ((newsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
return -1;
if (ioctlsocket (newsocket, FIONBIO, &_true) == -1)
goto ErrorReturn;
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons (port);
if (bind (newsocket, (void *) &address, sizeof (address)) == -1)
goto ErrorReturn;
return newsocket;
ErrorReturn:
closesocket (newsocket);
return -1;
}
//=============================================================================
int
MPATH_CloseSocket (int socket)
{
if (socket == net_broadcastsocket)
net_broadcastsocket = 0;
return closesocket (socket);
}
//=============================================================================
/*
============
PartialIPAddress
this lets you type only as much of the net address as required, using
the local network components to fill in the rest
============
*/
static int
PartialIPAddress (char *in, struct qsockaddr *hostaddr)
{
char buff[256];
char *b;
int addr;
int num;
int mask;
int run;
int port;
buff[0] = '.';
b = buff;
strcpy (buff + 1, in);
if (buff[1] == '.')
b++;
addr = 0;
mask = -1;
while (*b == '.') {
b++;
num = 0;
run = 0;
while (!(*b < '0' || *b > '9')) {
num = num * 10 + *b++ - '0';
if (++run > 3)
return -1;
}
if ((*b < '0' || *b > '9') && *b != '.' && *b != ':' && *b != 0)
return -1;
if (num < 0 || num > 255)
return -1;
mask <<= 8;
addr = (addr << 8) + num;
}
if (*b++ == ':')
port = Q_atoi (b);
else
port = net_hostport;
hostaddr->sa_family = AF_INET;
((struct sockaddr_in *) hostaddr)->sin_port = htons ((short) port);
((struct sockaddr_in *) hostaddr)->sin_addr.s_addr =
(myAddr & htonl (mask)) | htonl (addr);
return 0;
}
//=============================================================================
int
MPATH_Connect (int socket, struct qsockaddr *addr)
{
return 0;
}
//=============================================================================
int
MPATH_CheckNewConnections (void)
{
char buf[4];
if (net_acceptsocket == -1)
return -1;
if (recvfrom (net_acceptsocket, buf, 4, MSG_PEEK, NULL, NULL) >= 0)
return net_acceptsocket;
return -1;
}
//=============================================================================
int
MPATH_Read (int socket, byte * buf, int len, struct qsockaddr *addr)
{
int addrlen = sizeof (struct qsockaddr);
int ret;
ret = recvfrom (socket, buf, len, 0, (struct sockaddr *) addr, &addrlen);
if (ret == -1) {
int errno = WSAGetLastError ();
if (errno == WSAEWOULDBLOCK || errno == WSAECONNREFUSED)
return 0;
}
return ret;
}
//=============================================================================
int
MPATH_MakeSocketBroadcastCapable (int socket)
{
int i = 1;
// make this socket broadcast capable
if (setsockopt (socket, SOL_SOCKET, SO_BROADCAST, (char *) &i, sizeof (i)) <
0) return -1;
net_broadcastsocket = socket;
return 0;
}
//=============================================================================
int
MPATH_Broadcast (int socket, byte * buf, int len)
{
int ret;
if (socket != net_broadcastsocket) {
if (net_broadcastsocket != 0)
Sys_Error ("Attempted to use multiple broadcasts sockets");
ret = MPATH_MakeSocketBroadcastCapable (socket);
if (ret == -1) {
Con_Printf ("Unable to make socket broadcast capable\n");
return ret;
}
}
return MPATH_Write (socket, buf, len, &broadcastaddr);
}
//=============================================================================
int
MPATH_Write (int socket, byte * buf, int len, struct qsockaddr *addr)
{
int ret;
ret =
sendto (socket, buf, len, 0, (struct sockaddr *) addr,
sizeof (struct qsockaddr));
if (ret == -1)
if (WSAGetLastError () == WSAEWOULDBLOCK)
return 0;
sockets_flush ();
return ret;
}
//=============================================================================
char *
MPATH_AddrToString (struct qsockaddr *addr)
{
static char buffer[22];
int haddr;
haddr = ntohl (((struct sockaddr_in *) addr)->sin_addr.s_addr);
snprintf (buffer, sizeof (buffer), "%d.%d.%d.%d:%d", (haddr >> 24) & 0xff,
(haddr >> 16) & 0xff, (haddr >> 8) & 0xff, haddr & 0xff,
ntohs (((struct sockaddr_in *) addr)->sin_port));
return buffer;
}
//=============================================================================
int
MPATH_StringToAddr (char *string, struct qsockaddr *addr)
{
int ha1, ha2, ha3, ha4, hp;
int ipaddr;
sscanf (string, "%d.%d.%d.%d:%d", &ha1, &ha2, &ha3, &ha4, &hp);
ipaddr = (ha1 << 24) | (ha2 << 16) | (ha3 << 8) | ha4;
addr->sa_family = AF_INET;
((struct sockaddr_in *) addr)->sin_addr.s_addr = htonl (ipaddr);
((struct sockaddr_in *) addr)->sin_port = htons (hp);
return 0;
}
//=============================================================================
int
MPATH_GetSocketAddr (int socket, struct qsockaddr *addr)
{
int addrlen = sizeof (struct qsockaddr);
unsigned int a;
Q_memset (addr, 0, sizeof (struct qsockaddr));
getsockname (socket, (struct sockaddr *) addr, &addrlen);
a = ((struct sockaddr_in *) addr)->sin_addr.s_addr;
if (a == 0 || a == inet_addr ("127.0.0.1"))
((struct sockaddr_in *) addr)->sin_addr.s_addr = myAddr;
return 0;
}
//=============================================================================
int
MPATH_GetNameFromAddr (struct qsockaddr *addr, char *name)
{
struct hostent *hostentry;
hostentry =
gethostbyaddr ((char *) &((struct sockaddr_in *) addr)->sin_addr,
sizeof (struct in_addr), AF_INET);
if (hostentry) {
Q_strncpy (name, (char *) hostentry->h_name, NET_NAMELEN - 1);
return 0;
}
Q_strcpy (name, MPATH_AddrToString (addr));
return 0;
}
//=============================================================================
int
MPATH_GetAddrFromName (char *name, struct qsockaddr *addr)
{
struct hostent *hostentry;
if (name[0] >= '0' && name[0] <= '9')
return PartialIPAddress (name, addr);
hostentry = gethostbyname (name);
if (!hostentry)
return -1;
addr->sa_family = AF_INET;
((struct sockaddr_in *) addr)->sin_port = htons (net_hostport);
((struct sockaddr_in *) addr)->sin_addr.s_addr =
*(int *) hostentry->h_addr_list[0];
return 0;
}
//=============================================================================
int
MPATH_AddrCompare (struct qsockaddr *addr1, struct qsockaddr *addr2)
{
if (addr1->sa_family != addr2->sa_family)
return -1;
if (((struct sockaddr_in *) addr1)->sin_addr.s_addr !=
((struct sockaddr_in *) addr2)->sin_addr.s_addr)
return -1;
if (((struct sockaddr_in *) addr1)->sin_port !=
((struct sockaddr_in *) addr2)->sin_port)
return 1;
return 0;
}
//=============================================================================
int
MPATH_GetSocketPort (struct qsockaddr *addr)
{
return ntohs (((struct sockaddr_in *) addr)->sin_port);
}
int
MPATH_SetSocketPort (struct qsockaddr *addr, int port)
{
((struct sockaddr_in *) addr)->sin_port = htons (port);
return 0;
}
//=============================================================================

View file

@ -1,56 +0,0 @@
/*
net_none.c
@description@
Copyright (C) 1996-1997 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
static __attribute__ ((unused)) const char rcsid[] =
"$Id$";
#include "net_loop.h"
net_driver_t net_drivers[MAX_NET_DRIVERS] = {
{
"Loopback",
false,
Loop_Init,
Loop_Listen,
Loop_SearchForHosts,
Loop_Connect,
Loop_CheckNewConnections,
Loop_GetMessage,
Loop_SendMessage,
Loop_SendUnreliableMessage,
Loop_CanSendMessage,
Loop_CanSendUnreliableMessage,
Loop_Close,
Loop_Shutdown}
};
int net_numdrivers = 1;
net_landriver_t net_landrivers[MAX_NET_DRIVERS];
int net_numlandrivers = 0;

View file

@ -1,471 +0,0 @@
/*
net_wipx.c
@description@
Copyright (C) 1996-1997 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
static __attribute__ ((unused)) const char rcsid[] =
"$Id$";
#include "winquake.h"
#include <wsipx.h>
#include "QF/console.h"
#include "QF/cvar.h"
#include "QF/qargs.h"
#include "QF/sys.h"
#include "game.h"
#include "net_wins.h"
#include "net_wipx.h"
#define MAXHOSTNAMELEN 256
static int net_acceptsocket = -1; // socket for fielding new
// connections
static int net_controlsocket;
static struct qsockaddr broadcastaddr;
#define IPXSOCKETS 18
static int ipxsocket[IPXSOCKETS];
static int sequence[IPXSOCKETS];
//=============================================================================
int
WIPX_Init (void)
{
int i;
char buff[MAXHOSTNAMELEN];
struct qsockaddr addr;
char *p;
int r;
WORD wVersionRequested;
if (COM_CheckParm ("-noipx"))
return -1;
// make sure LoadLibrary has happened successfully
if (!winsock_lib_initialized)
return -1;
if (winsock_initialized == 0) {
wVersionRequested = MAKEWORD (1, 1);
r = pWSAStartup (MAKEWORD (1, 1), &winsockdata);
if (r) {
Con_Printf ("Winsock initialization failed.\n");
return -1;
}
}
winsock_initialized++;
for (i = 0; i < IPXSOCKETS; i++)
ipxsocket[i] = 0;
// determine my name & address
if (pgethostname (buff, MAXHOSTNAMELEN) == 0) {
// if the quake hostname isn't set, set it to the machine name
if (strcmp (hostname->string, "UNNAMED") == 0) {
// see if it's a text IP address (well, close enough)
for (p = buff; *p; p++)
if ((*p < '0' || *p > '9') && *p != '.')
break;
// if it is a real name, strip off the domain; we only want the
// host
if (*p) {
for (i = 0; i < 15; i++)
if (buff[i] == '.')
break;
buff[i] = 0;
}
Cvar_Set (hostname, buff);
}
}
if ((net_controlsocket = WIPX_OpenSocket (0)) == -1) {
Con_Printf ("WIPX_Init: Unable to open control socket\n");
if (--winsock_initialized == 0)
pWSACleanup ();
return -1;
}
((struct sockaddr_ipx *) &broadcastaddr)->sa_family = AF_IPX;
memset (((struct sockaddr_ipx *) &broadcastaddr)->sa_netnum, 0, 4);
memset (((struct sockaddr_ipx *) &broadcastaddr)->sa_nodenum, 0xff, 6);
((struct sockaddr_ipx *) &broadcastaddr)->sa_socket =
htons ((unsigned short) net_hostport);
WIPX_GetSocketAddr (net_controlsocket, &addr);
strcpy (my_ipx_address, WIPX_AddrToString (&addr));
p = strrchr (my_ipx_address, ':');
if (p)
*p = 0;
Con_Printf ("Winsock IPX Initialized\n");
ipxAvailable = true;
return net_controlsocket;
}
//=============================================================================
void
WIPX_Shutdown (void)
{
WIPX_Listen (false);
WIPX_CloseSocket (net_controlsocket);
if (--winsock_initialized == 0)
pWSACleanup ();
}
//=============================================================================
void
WIPX_Listen (qboolean state)
{
// enable listening
if (state) {
if (net_acceptsocket != -1)
return;
if ((net_acceptsocket = WIPX_OpenSocket (net_hostport)) == -1)
Sys_Error ("WIPX_Listen: Unable to open accept socket");
return;
}
// disable listening
if (net_acceptsocket == -1)
return;
WIPX_CloseSocket (net_acceptsocket);
net_acceptsocket = -1;
}
//=============================================================================
int
WIPX_OpenSocket (int port)
{
int handle;
int newsocket;
struct sockaddr_ipx address;
u_long _true = 1;
for (handle = 0; handle < IPXSOCKETS; handle++)
if (ipxsocket[handle] == 0)
break;
if (handle == IPXSOCKETS)
return -1;
if ((newsocket = psocket (AF_IPX, SOCK_DGRAM, NSPROTO_IPX)) ==
INVALID_SOCKET) return -1;
if (pioctlsocket (newsocket, FIONBIO, &_true) == -1)
goto ErrorReturn;
if (psetsockopt
(newsocket, SOL_SOCKET, SO_BROADCAST, (char *) &_true,
sizeof (_true)) < 0) goto ErrorReturn;
address.sa_family = AF_IPX;
memset (address.sa_netnum, 0, 4);
memset (address.sa_nodenum, 0, 6);
address.sa_socket = htons ((unsigned short) port);
if (bind (newsocket, (void *) &address, sizeof (address)) == 0) {
ipxsocket[handle] = newsocket;
sequence[handle] = 0;
return handle;
}
Sys_Error ("Winsock IPX bind failed");
ErrorReturn:
pclosesocket (newsocket);
return -1;
}
//=============================================================================
int
WIPX_CloseSocket (int handle)
{
int socket = ipxsocket[handle];
int ret;
ret = pclosesocket (socket);
ipxsocket[handle] = 0;
return ret;
}
//=============================================================================
int
WIPX_Connect (int handle, struct qsockaddr *addr)
{
return 0;
}
//=============================================================================
int
WIPX_CheckNewConnections (void)
{
unsigned long available;
if (net_acceptsocket == -1)
return -1;
if (pioctlsocket (ipxsocket[net_acceptsocket], FIONREAD, &available) == -1)
Sys_Error ("WIPX: ioctlsocket (FIONREAD) failed");
if (available)
return net_acceptsocket;
return -1;
}
//=============================================================================
static byte packetBuffer[NET_DATAGRAMSIZE + 4];
int
WIPX_Read (int handle, byte * buf, int len, struct qsockaddr *addr)
{
int addrlen = sizeof (struct qsockaddr);
int socket = ipxsocket[handle];
int ret;
ret =
precvfrom (socket, packetBuffer, len + 4, 0, (struct sockaddr *) addr,
&addrlen);
if (ret == -1) {
int errno = pWSAGetLastError ();
if (errno == WSAEWOULDBLOCK || errno == WSAECONNREFUSED)
return 0;
}
if (ret < 4)
return 0;
// remove sequence number, it's only needed for DOS IPX
ret -= 4;
memcpy (buf, packetBuffer + 4, ret);
return ret;
}
//=============================================================================
int
WIPX_Broadcast (int handle, byte * buf, int len)
{
return WIPX_Write (handle, buf, len, &broadcastaddr);
}
//=============================================================================
int
WIPX_Write (int handle, byte * buf, int len, struct qsockaddr *addr)
{
int socket = ipxsocket[handle];
int ret;
// build packet with sequence number
*(int *) (&packetBuffer[0]) = sequence[handle];
sequence[handle]++;
memcpy (&packetBuffer[4], buf, len);
len += 4;
ret =
psendto (socket, packetBuffer, len, 0, (struct sockaddr *) addr,
sizeof (struct qsockaddr));
if (ret == -1)
if (pWSAGetLastError () == WSAEWOULDBLOCK)
return 0;
return ret;
}
//=============================================================================
char *
WIPX_AddrToString (struct qsockaddr *addr)
{
static char buf[28];
snprintf (buf, sizeof (buf), "%02x%02x%02x%02x:%02x%02x%02x%02x%02x%02x:%u",
((struct sockaddr_ipx *) addr)->sa_netnum[0] & 0xff,
((struct sockaddr_ipx *) addr)->sa_netnum[1] & 0xff,
((struct sockaddr_ipx *) addr)->sa_netnum[2] & 0xff,
((struct sockaddr_ipx *) addr)->sa_netnum[3] & 0xff,
((struct sockaddr_ipx *) addr)->sa_nodenum[0] & 0xff,
((struct sockaddr_ipx *) addr)->sa_nodenum[1] & 0xff,
((struct sockaddr_ipx *) addr)->sa_nodenum[2] & 0xff,
((struct sockaddr_ipx *) addr)->sa_nodenum[3] & 0xff,
((struct sockaddr_ipx *) addr)->sa_nodenum[4] & 0xff,
((struct sockaddr_ipx *) addr)->sa_nodenum[5] & 0xff,
ntohs (((struct sockaddr_ipx *) addr)->sa_socket)
);
return buf;
}
//=============================================================================
int
WIPX_StringToAddr (char *string, struct qsockaddr *addr)
{
int val;
char buf[3];
buf[2] = 0;
memset (addr, 0, sizeof (struct qsockaddr));
addr->sa_family = AF_IPX;
#define DO(src,dest) \
buf[0] = string[src]; \
buf[1] = string[src + 1]; \
if (sscanf (buf, "%x", &val) != 1) \
return -1; \
((struct sockaddr_ipx *)addr)->dest = val
DO (0, sa_netnum[0]);
DO (2, sa_netnum[1]);
DO (4, sa_netnum[2]);
DO (6, sa_netnum[3]);
DO (9, sa_nodenum[0]);
DO (11, sa_nodenum[1]);
DO (13, sa_nodenum[2]);
DO (15, sa_nodenum[3]);
DO (17, sa_nodenum[4]);
DO (19, sa_nodenum[5]);
#undef DO
sscanf (&string[22], "%u", &val);
((struct sockaddr_ipx *) addr)->sa_socket = htons ((unsigned short) val);
return 0;
}
//=============================================================================
int
WIPX_GetSocketAddr (int handle, struct qsockaddr *addr)
{
int socket = ipxsocket[handle];
int addrlen = sizeof (struct qsockaddr);
unsigned int a;
memset (addr, 0, sizeof (struct qsockaddr));
if (pgetsockname (socket, (struct sockaddr *) addr, &addrlen) != 0) {
int errno = pWSAGetLastError ();
}
return 0;
}
//=============================================================================
int
WIPX_GetNameFromAddr (struct qsockaddr *addr, char *name)
{
strcpy (name, WIPX_AddrToString (addr));
return 0;
}
//=============================================================================
int
WIPX_GetAddrFromName (char *name, struct qsockaddr *addr)
{
int n;
char buf[32];
n = strlen (name);
if (n == 12) {
snprintf (buf, sizeof (buf), "00000000:%s:%u", name, net_hostport);
return WIPX_StringToAddr (buf, addr);
}
if (n == 21) {
snprintf (buf, sizeof (buf), "%s:%u", name, net_hostport);
return WIPX_StringToAddr (buf, addr);
}
if (n > 21 && n <= 27)
return WIPX_StringToAddr (name, addr);
return -1;
}
//=============================================================================
int
WIPX_AddrCompare (struct qsockaddr *addr1, struct qsockaddr *addr2)
{
if (addr1->sa_family != addr2->sa_family)
return -1;
if (*((struct sockaddr_ipx *) addr1)->sa_netnum
&& *((struct sockaddr_ipx *) addr2)->sa_netnum)
if (memcmp
(((struct sockaddr_ipx *) addr1)->sa_netnum,
((struct sockaddr_ipx *) addr2)->sa_netnum, 4) != 0)
return -1;
if (memcmp
(((struct sockaddr_ipx *) addr1)->sa_nodenum,
((struct sockaddr_ipx *) addr2)->sa_nodenum, 6) != 0)
return -1;
if (((struct sockaddr_ipx *) addr1)->sa_socket !=
((struct sockaddr_ipx *) addr2)->sa_socket)
return 1;
return 0;
}
//=============================================================================
int
WIPX_GetSocketPort (struct qsockaddr *addr)
{
return ntohs (((struct sockaddr_ipx *) addr)->sa_socket);
}
int
WIPX_SetSocketPort (struct qsockaddr *addr, int port)
{
((struct sockaddr_ipx *) addr)->sa_socket = htons ((unsigned short) port);
return 0;
}
//=============================================================================