19fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream/*
29fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamCopyright (C) 1996-1997 Id Software, Inc.
39fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
49fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamThis program is free software; you can redistribute it and/or
59fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreammodify it under the terms of the GNU General Public License
69fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamas published by the Free Software Foundation; either version 2
79fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamof the License, or (at your option) any later version.
89fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
99fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamThis program is distributed in the hope that it will be useful,
109fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreambut WITHOUT ANY WARRANTY; without even the implied warranty of
119fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
129fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
139fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamSee the GNU General Public License for more details.
149fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
159fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamYou should have received a copy of the GNU General Public License
169fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamalong with this program; if not, write to the Free Software
179fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
189fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
199fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream*/
209fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// net_bw.c
219fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
229fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#include <stdio.h>
239fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#include <stdlib.h>
249fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#include <dpmi.h>
259fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
269fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#include "quakedef.h"
279fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#include "dosisms.h"
289fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
299fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
309fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// this section is general Unix stuff that we need
319fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
329fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define	EIO		 		5	/* I/O error */
339fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define EBADS			9
349fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define EWOULDBLOCK		35	/* function would block */
359fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define EMSGSIZE		40	/* message to big for buffers */
369fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define	EPROTONOSUPPORT	43	/* Protocol not supported */
379fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define	ESOCKTNOSUPPORT	44	/* Socket type not supported */
389fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define	EPFNOSUPPORT	46	/* Protocol family not supported */
399fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define EAFNOSUPPORT	47	/* Address family not supported */
409fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define ECONNABORTED	53	/* User requested hangup */
419fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define ENOBUFS 		55	/* No buffers available */
429fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define EISCONN 		56	/* Socket has closed */
439fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define ENOTCONN		57	/* Socket is not connected */
449fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define ESHUTDOWN		58	/* Socket is closed */
459fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define ETOOMANYREFS	59	/* Too many sockets open */
469fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define ETIMEDOUT		60	/* Connection timed out */
479fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define ECONNREFUSED	61	/* Connection refused */
489fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
499fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define AF_INET 		2	/* internet */
509fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
519fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define PF_INET			AF_INET
529fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
539fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define SOCK_STREAM		1		/* stream */
549fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define SOCK_DGRAM		2		/* datagram */
559fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
569fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define IPPROTO_TCP		6
579fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define IPPROTO_UDP		17
589fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
599fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define INADDR_ANY		0
609fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
619fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define SIOCDONE		0x7300
629fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define FIONREAD		0x667f
639fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define FIONBIO 		0x667e
649fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define FIONWIN 		0x1000
659fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define FIONTIN 		0x2000
669fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
679fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define BRDINIT 		0
689fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define BRDADDR 		10
699fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
709fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define MAXHOSTNAMELEN	256
719fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
729fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define SOL_SOCKET		0xffff		/* options for socket level */
739fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
749fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream/*
759fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream * Option flags per-socket.
769fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream */
779fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define SO_DEBUG		0x0001		/* turn on debugging info recording */
789fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define SO_ACCEPTCONN	0x0002		/* socket has had listen() */
799fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define SO_REUSEADDR	0x0004		/* allow local address reuse */
809fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define SO_KEEPALIVE	0x0008		/* keep connections alive */
819fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define SO_DONTROUTE	0x0010		/* just use interface addresses */
829fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define SO_BROADCAST	0x0020		/* permit sending of broadcast msgs */
839fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define SO_USELOOPBACK	0x0040		/* bypass hardware when possible */
849fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define SO_LINGER		0x0080		/* linger on close if data present */
859fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define SO_OOBINLINE	0x0100		/* leave received OOB data in line */
869fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define SO_USEPRIV		0x4000		/* allocate from privileged port area */
879fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define SO_CANTSIG		0x8000		/* prevent SIGPIPE on SS_CANTSENDMORE */
889fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
899fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream/*
909fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream * Additional options, not kept in so_options.
919fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream */
929fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define SO_SNDBUF		0x1001		/* send buffer size */
939fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define SO_RCVBUF		0x1002		/* receive buffer size */
949fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define SO_SNDLOWAT		0x1003		/* send low-water mark */
959fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define SO_RCVLOWAT		0x1004		/* receive low-water mark */
969fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define SO_SNDTIMEO		0x1005		/* send timeout */
979fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define SO_RCVTIMEO		0x1006		/* receive timeout */
989fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define SO_ERROR		0x1007		/* get error status and clear */
999fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define SO_TYPE			0x1008		/* get socket type */
1009fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1019fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1029fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamstruct in_addr
1039fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
1049fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	union
1059fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
1069fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		struct { unsigned char s_b1,s_b2,s_b3,s_b4; } S_un_b;
1079fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		struct { unsigned short s_w1,s_w2; } S_un_w;
1089fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		unsigned long S_addr;
1099fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	} S_un;
1109fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream};
1119fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define	s_addr	S_un.S_addr	/* can be used for most tcp & ip code */
1129fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define	s_host	S_un.S_un_b.s_b2	/* host on imp */
1139fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define	s_net	S_un.S_un_b.s_b1	/* network */
1149fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define	s_imp	S_un.S_un_w.s_w2	/* imp */
1159fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define	s_impno	S_un.S_un_b.s_b4	/* imp # */
1169fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define	s_lh	S_un.S_un_b.s_b3	/* logical host */
1179fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1189fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamstruct sockaddr_in
1199fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
1209fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream    short			sin_family;
1219fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream    unsigned short	sin_port;
1229fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	struct in_addr	sin_addr;
1239fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream    char			sin_zero[8];
1249fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream};
1259fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1269fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamstruct	hostent {
1279fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	char	*h_name;	/* official name of host */
1289fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	char	**h_aliases;	/* alias list */
1299fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	int	h_addrtype;	/* host address type */
1309fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	int	h_length;	/* length of address */
1319fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	char	**h_addr_list;	/* list of addresses from name server */
1329fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define	h_addr	h_addr_list[0]	/* address, for backward compatiblity */
1339fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream};
1349fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1359fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamchar *inet_ntoa(struct in_addr in);
1369fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1379fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1389fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// this section is B&W specific constants & structures
1399fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1409fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define BW_IOCTL_BIND			0
1419fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define BW_IOCTL_CLEAROPTIONS	5
1429fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define BW_IOCTL_SETOPTIONS		6
1439fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define BW_IOCTL_PEEK			7
1449fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define BW_IOCTL_SETWINMASK		8
1459fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1469fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define BW_OPTION_BLOCKING		0x01
1479fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define BW_OPTION_REUSEBUFFERS	0x80
1489fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1499fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define BW_ERR_USR_HANGUP		50
1509fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define BW_ERR_HANGUP			51
1519fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define BW_ERR_NET_ERR			52
1529fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define BW_ERR_IS_CLOSED		53
1539fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define BW_ERR_TIME_OUT			54
1549fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define BW_ERR_RESET			55
1559fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define BW_ERR_FULL				56
1569fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define BW_ERR_BLOCK			57
1579fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define BW_ERR_SHUTDOWN			58
1589fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1599fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#pragma pack(1)
1609fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1619fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamtypedef struct
1629fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
1639fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	char			state;			// always 1
1649fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	short			localPort;
1659fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	struct in_addr	localAddr;
1669fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	char			reason;			// always 0
1679fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	char			options;
1689fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	short			dataAvailable;
1699fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream} BW_UDPinfo_t;
1709fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1719fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamtypedef struct
1729fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
1739fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	char			reserved1 [6];
1749fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	unsigned short	info2Offset;
1759fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	char			reserved2 [18];
1769fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	struct in_addr	remoteAddr;
1779fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream} BW_UDPreadInfo1_t;
1789fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1799fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamtypedef struct
1809fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
1819fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	short			remotePort;
1829fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	char			reserved1 [2];
1839fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	unsigned short	dataLenPlus8;
1849fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	char			reserved2 [2];
1859fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	char			data[1];			// actual size is <dataLenPlus8> - 8
1869fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream} BW_UDPreadInfo2_t;
1879fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1889fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamtypedef struct
1899fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
1909fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	char			reserved1 [2];
1919fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	short			remotePort;
1929fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	unsigned short	dataLen;
1939fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	struct in_addr	remoteAddr;
1949fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	char			reserved2 [42];
1959fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	char			data[1];			// actual size is <datalen>
1969fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream} BW_writeInfo_t;
1979fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1989fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamtypedef struct
1999fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
2009fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	short	ioport;
2019fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	byte	dma;
2029fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	byte	vector;
2039fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	byte	irq;
2049fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	short	bufferSize;
2059fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	short	maxWindow;
2069fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	short	timeZone;
2079fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	byte	myType;
2089fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	int		inetAddr;
2099fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	short	value;
2109fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	byte	subnetMask;
2119fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	short	etherPointer;
2129fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	short	logserverPointer;
2139fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	short	nameserverPointer;
2149fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	short	printserverPointer;
2159fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	short	timeserverPointer;
2169fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	short	gatewayPointer;
2179fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	short	driverSegment;
2189fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	byte	transferSize;
2199fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	char	cardName [9];
2209fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream} BW_ethdevinfo_t;
2219fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2229fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#pragma pack()
2239fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2249fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define LOWMEM_SIZE	4096
2259fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2269fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamstatic unsigned char *lowmem_buffer;
2279fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamstatic int lowmem_bufseg;
2289fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamstatic int lowmem_bufoff;
2299fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamstatic BW_ethdevinfo_t ethdevinfo;
2309fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamstatic int netmask;
2319fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamstatic struct in_addr bcastaddr;
2329fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2339fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamextern regs_t regs;
2349fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2359fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamstatic int net_acceptsocket = -1;		// socket for fielding new connections
2369fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamstatic int net_controlsocket = 0;
2379fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2389fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#include "net_bw.h"
2399fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2409fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream//=============================================================================
2419fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2429fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamstatic int BW_ioctl(int s, char *msg, int msglen)
2439fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
2449fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	Q_memcpy(lowmem_buffer, msg, msglen);
2459fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2469fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.ax = 0x4403;
2479fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.bx = s;
2489fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.cx = msglen;
2499fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.dx = lowmem_bufoff;
2509fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.ds = lowmem_bufseg;
2519fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (dos_int86(0x21))
2529fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return regs.x.ax;
2539fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	return 0;
2549fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
2559fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2569fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream//=============================================================================
2579fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2589fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamstatic int BW_TranslateError(int error)
2599fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
2609fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	switch(error)
2619fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
2629fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		case BW_ERR_USR_HANGUP:	return ECONNABORTED;
2639fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		case BW_ERR_HANGUP:		return EISCONN;
2649fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		case BW_ERR_NET_ERR:	return ENOTCONN;
2659fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		case BW_ERR_IS_CLOSED:	return ENOTCONN;
2669fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		case BW_ERR_TIME_OUT:	return ETIMEDOUT;
2679fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		case BW_ERR_RESET:		return ECONNREFUSED;
2689fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		case BW_ERR_FULL:		return ETOOMANYREFS;
2699fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		case BW_ERR_BLOCK:		return EWOULDBLOCK;
2709fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		case BW_ERR_SHUTDOWN:	return ESHUTDOWN;
2719fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
2729fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	return EIO;
2739fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
2749fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2759fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream//=============================================================================
2769fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2779fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamstatic int GetEthdevinfo(void)
2789fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
2799fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	int fd;
2809fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2819fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	Q_strcpy((char *)lowmem_buffer, "ETHDEV27");
2829fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.ax = 0x3d42;
2839fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.ds = lowmem_bufseg;
2849fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.dx = lowmem_bufoff;
2859fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (dos_int86(0x21))
2869fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return -1;
2879fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	fd = regs.x.ax;
2889fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2899fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.ax = 0x4401;
2909fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.bx = fd;
2919fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.dx = 0x60;
2929fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	dos_int86(0x21);
2939fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2949fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.h.ah = 0x3f;
2959fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.cx = sizeof(ethdevinfo);
2969fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.es = regs.x.ds = lowmem_bufseg;
2979fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.dx = lowmem_bufoff;
2989fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.bx = fd;
2999fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (dos_int86(0x21))
3009fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return -1;
3019fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	Q_memcpy(&ethdevinfo, lowmem_buffer, regs.x.ax);
3029fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3039fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.h.ah = 0x3e;
3049fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.bx = fd;
3059fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	dos_int86(0x21);
3069fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3079fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	return 0;
3089fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
3099fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3109fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream//=============================================================================
3119fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3129fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamint BW_Init(void)
3139fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
3149fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	struct qsockaddr addr;
3159fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	char *colon;
3169fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3179fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (COM_CheckParm ("-noudp"))
3189fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return -1;
3199fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3209fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	lowmem_buffer = dos_getmemory(LOWMEM_SIZE);
3219fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (!lowmem_buffer)
3229fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		Sys_Error("not enough low memory\n");
3239fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	lowmem_bufoff = ptr2real(lowmem_buffer) & 0xf;
3249fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	lowmem_bufseg = ptr2real(lowmem_buffer) >> 4;
3259fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3269fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (GetEthdevinfo())
3279fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
3289fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		Con_DPrintf("Beame & Whiteside TCP/IP not detected\n");
3299fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		dos_freememory(lowmem_buffer);
3309fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return -1;
3319fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
3329fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	netmask = 0xffffffff >> (32 - ethdevinfo.subnetMask);
3339fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	bcastaddr.s_addr = (ethdevinfo.inetAddr & netmask) | (~netmask);
3349fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3359fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if ((net_controlsocket = BW_OpenSocket (0)) == -1)
3369fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
3379fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		dos_freememory(lowmem_buffer);
3389fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		Con_DPrintf ("BW_Init unable to open control socket; disabled\n");
3399fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return -1;
3409fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
3419fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3429fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	BW_GetSocketAddr (net_controlsocket, &addr);
3439fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	Q_strcpy(my_tcpip_address,  BW_AddrToString (&addr));
3449fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	colon = Q_strrchr (my_tcpip_address, ':');
3459fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (colon)
3469fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		*colon = 0;
3479fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3489fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	Con_Printf("BW_Init: UDP initialized\n");
3499fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	tcpipAvailable = true;
3509fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3519fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	return net_controlsocket;
3529fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
3539fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3549fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream//=============================================================================
3559fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3569fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamvoid BW_Shutdown(void)
3579fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
3589fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	BW_Listen (false);
3599fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	BW_CloseSocket (net_controlsocket);
3609fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	dos_freememory(lowmem_buffer);
3619fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
3629fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3639fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream//=============================================================================
3649fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3659fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamvoid BW_Listen (qboolean state)
3669fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
3679fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	// enable listening
3689fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (state)
3699fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
3709fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		if (net_acceptsocket != -1)
3719fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			return;
3729fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		if ((net_acceptsocket = BW_OpenSocket (net_hostport)) == -1)
3739fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			Sys_Error ("BW_Listen: Unable to open accept socket\n");
3749fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return;
3759fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
3769fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3779fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	// disable listening
3789fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (net_acceptsocket == -1)
3799fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return;
3809fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	BW_CloseSocket (net_acceptsocket);
3819fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	net_acceptsocket = -1;
3829fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
3839fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3849fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3859fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream//=============================================================================
3869fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3879fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream/*
3889fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamOpenSocket returns a handle to a network socket that has been opened,
3899fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamset to nonblocking, and bound to <port>.  Additional socket options
3909fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamshould be set here if they are needed.  -1 is returned on failure.
3919fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream*/
3929fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3939fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamint BW_OpenSocket(int port)
3949fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
3959fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	int s;
3969fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	int ret;
3979fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	int deadman = 3 * 1024;
3989fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	static int dynamic = 1024;
3999fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	static char reuse_msg[2] = {BW_IOCTL_SETOPTIONS, BW_OPTION_REUSEBUFFERS};
4009fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	static char bind_msg[3] = {BW_IOCTL_BIND, 0, 0};
4019fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	static char nonblock_msg[2] = {BW_IOCTL_CLEAROPTIONS, BW_OPTION_BLOCKING};
4029fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
4039fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	// allocate a UDP socket
4049fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	Q_strcpy((char *)lowmem_buffer, "UDP-IP10");
4059fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.ax = 0x3d42;
4069fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.ds = lowmem_bufseg;
4079fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.dx = lowmem_bufoff;
4089fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (dos_int86(0x21))
4099fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
4109fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		Con_Printf("BW_OpenSocket failed: %u\n", BW_TranslateError(regs.x.ax));
4119fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return -1;
4129fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
4139fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	s = regs.x.ax;
4149fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
4159fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	// set file descriptor to raw mode
4169fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.ax = 0x4401;
4179fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.bx = s;
4189fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.dx = 0x60;
4199fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	dos_int86(0x21);
4209fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
4219fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (BW_ioctl(s, reuse_msg, 2))
4229fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
4239fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		Con_Printf("BW_OpenSocket ioctl(reuse) failed\n");
4249fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return -1;
4259fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
4269fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
4279fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (BW_ioctl(s, nonblock_msg, 2))
4289fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
4299fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		Con_Printf("BW_OpenSocket ioctl(nonblocking) failed\n");
4309fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return -1;
4319fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
4329fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
4339fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	// if a socket was specified, bind to it and return
4349fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (port)
4359fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
4369fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		*(short *)&bind_msg[1] = port;
4379fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		if (BW_ioctl(s, bind_msg, 3))
4389fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		{
4399fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			BW_CloseSocket(s);
4409fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			return -1;
4419fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		}
4429fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return s;
4439fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
4449fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
4459fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	// B&W does NOT do dynamic allocation, so if port == 0 we must fake it
4469fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	do
4479fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
4489fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		port = dynamic++;
4499fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		if (dynamic == 4096)
4509fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			dynamic = 1024;
4519fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		deadman--;
4529fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		*(short *)&bind_msg[1] = port;
4539fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		ret = BW_ioctl(s, bind_msg, 3);
4549fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
4559fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	while (ret && deadman);
4569fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (ret)
4579fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return -1;
4589fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	return s;
4599fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
4609fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
4619fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream//=============================================================================
4629fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
4639fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamint BW_CloseSocket(int socket)
4649fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
4659fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.h.ah = 0x3e;
4669fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.bx = socket;
4679fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if(dos_int86(0x21))
4689fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		{
4699fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			Con_Printf("BW_CloseSocket %u failed: %u\n", socket, BW_TranslateError(regs.x.ax));
4709fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			return -1;
4719fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		}
4729fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	return 0;
4739fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
4749fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
4759fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream//=============================================================================
4769fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
4779fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamint BW_Connect (int socket, struct qsockaddr *hostaddr)
4789fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
4799fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	return 0;
4809fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
4819fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
4829fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream//=============================================================================
4839fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
4849fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamint BW_CheckNewConnections(void)
4859fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
4869fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (net_acceptsocket == 0)
4879fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return -1;
4889fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
4899fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	// see if there's anything waiting
4909fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.ax = 0x4406;
4919fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.bx = net_acceptsocket;
4929fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	dos_int86(0x21);
4939fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (regs.x.ax == 0)
4949fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return -1;
4959fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	return net_acceptsocket;
4969fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
4979fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
4989fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream//=============================================================================
4999fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
5009fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamint BW_Read(int s, byte *buf, int len, struct qsockaddr *from)
5019fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
5029fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	BW_UDPreadInfo1_t *info1;
5039fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	BW_UDPreadInfo2_t *info2;
5049fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
5059fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	// ask if there's anything waiting
5069fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.ax = 0x4406;
5079fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.bx = s;
5089fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	dos_int86(0x21);
5099fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (regs.x.ax == 0)
5109fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return 0;
5119fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
5129fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	// there was, so let's get it
5139fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.h.ah = 0x3f;
5149fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.cx = /* len + 53 */ LOWMEM_SIZE;
5159fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.es = regs.x.ds = lowmem_bufseg;
5169fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.dx = lowmem_bufoff;
5179fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.bx = s;
5189fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (dos_int86(0x21))
5199fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
5209fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		Con_Printf("BW UDP read error: %u\n", BW_TranslateError(regs.x.ax));
5219fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return -1;
5229fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
5239fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
5249fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	info1 = (BW_UDPreadInfo1_t *)lowmem_buffer;
5259fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	info2 = (BW_UDPreadInfo2_t *)(lowmem_buffer + info1->info2Offset);
5269fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
5279fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (from)
5289fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
5299fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		from->sa_family = AF_INET;
5309fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		((struct sockaddr_in *)from)->sin_addr = info1->remoteAddr;
5319fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		((struct sockaddr_in *)from)->sin_port = htons(info2->remotePort);
5329fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
5339fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
5349fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	len = info2->dataLenPlus8 - 8;
5359fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (len > NET_DATAGRAMSIZE)
5369fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
5379fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		Con_Printf("BW UDP read packet too large: %u\n", len);
5389fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return -1;
5399fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
5409fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	Q_memcpy(buf, info2->data, len);
5419fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
5429fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	return len;
5439fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
5449fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
5459fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream//=============================================================================
5469fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
5479fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamint BW_Broadcast(int s, byte *msg, int len)
5489fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
5499fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	BW_writeInfo_t *writeInfo;
5509fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
5519fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	// ask if we're clear to send
5529fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.ax = 0x4407;
5539fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.bx = s;
5549fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	dos_int86(0x21);
5559fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (regs.x.ax == 0)
5569fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return 0;
5579fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
5589fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	// yes, let's do it
5599fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	writeInfo = (BW_writeInfo_t *)lowmem_buffer;
5609fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	writeInfo->remoteAddr = bcastaddr;
5619fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	writeInfo->remotePort = net_hostport;
5629fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	writeInfo->dataLen = len;
5639fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (len > NET_DATAGRAMSIZE)
5649fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		Sys_Error("BW UDP write packet too large: %u\n", len);
5659fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	Q_memcpy(writeInfo->data, msg, len);
5669fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	writeInfo->data[len] = 0;
5679fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.h.ah = 0x40;
5689fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.bx = s;
5699fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.cx = len + sizeof(BW_writeInfo_t);
5709fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.es = regs.x.ds = lowmem_bufseg;
5719fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.dx = lowmem_bufoff;
5729fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (dos_int86(0x21))
5739fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
5749fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		Con_Printf("BW_Broadcast failed: %u\n", BW_TranslateError(regs.x.ax));
5759fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return -1;
5769fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
5779fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
5789fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	return len;
5799fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
5809fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
5819fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream//=============================================================================
5829fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
5839fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamint BW_Write(int s, byte *msg, int len, struct qsockaddr *to)
5849fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
5859fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	BW_writeInfo_t *writeInfo;
5869fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
5879fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	// ask if we're clear to send
5889fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.ax = 0x4407;
5899fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.bx = s;
5909fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	dos_int86(0x21);
5919fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (regs.x.ax == 0)
5929fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return 0;
5939fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
5949fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	// yes, let's do it
5959fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	writeInfo = (BW_writeInfo_t *)lowmem_buffer;
5969fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	writeInfo->remoteAddr = ((struct sockaddr_in *)to)->sin_addr;
5979fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	writeInfo->remotePort = ntohs(((struct sockaddr_in *)to)->sin_port);
5989fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	writeInfo->dataLen = len;
5999fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (len > NET_DATAGRAMSIZE)
6009fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		Sys_Error("BW UDP write packet too large: %u\n", len);
6019fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	Q_memcpy(writeInfo->data, msg, len);
6029fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	writeInfo->data[len] = 0;
6039fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.h.ah = 0x40;
6049fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.bx = s;
6059fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.cx = len + sizeof(BW_writeInfo_t);
6069fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.es = regs.x.ds = lowmem_bufseg;
6079fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.dx = lowmem_bufoff;
6089fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (dos_int86(0x21))
6099fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
6109fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		Con_Printf("BW_Write failed: %u\n", BW_TranslateError(regs.x.ax));
6119fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return -1;
6129fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
6139fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
6149fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	return len;
6159fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
6169fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
6179fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream//=============================================================================
6189fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
6199fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
6209fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamchar *BW_AddrToString (struct qsockaddr *addr)
6219fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
6229fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	static char buffer[22];
6239fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
6249fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	sprintf(buffer, "%d.%d.%d.%d:%d",
6259fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		((struct sockaddr_in *)addr)->sin_addr.s_net,
6269fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		((struct sockaddr_in *)addr)->sin_addr.s_host,
6279fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		((struct sockaddr_in *)addr)->sin_addr.s_lh,
6289fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		((struct sockaddr_in *)addr)->sin_addr.s_impno,
6299fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		ntohs(((struct sockaddr_in *)addr)->sin_port)
6309fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		);
6319fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	return buffer;
6329fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
6339fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
6349fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream//=============================================================================
6359fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
6369fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamint BW_StringToAddr (char *string, struct qsockaddr *addr)
6379fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
6389fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	int ha1, ha2, ha3, ha4, hp;
6399fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	int ipaddr;
6409fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
6419fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	sscanf(string, "%d.%d.%d.%d:%d", &ha1, &ha2, &ha3, &ha4, &hp);
6429fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	ipaddr = (ha1 << 24) | (ha2 << 16) | (ha3 << 8) | ha4;
6439fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
6449fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	addr->sa_family = AF_INET;
6459fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	((struct sockaddr_in *)addr)->sin_addr.s_addr = htonl(ipaddr);
6469fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	((struct sockaddr_in *)addr)->sin_port = htons((short)hp);
6479fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	return 0;
6489fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
6499fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
6509fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream//=============================================================================
6519fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
6529fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamint BW_GetSocketAddr (int socket, struct qsockaddr *addr)
6539fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
6549fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.ax = 0x4402;
6559fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.bx = socket;
6569fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.cx = sizeof(BW_UDPinfo_t);
6579fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.dx = lowmem_bufoff;
6589fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	regs.x.ds = lowmem_bufseg;
6599fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	dos_int86(0x21);
6609fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
6619fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	addr->sa_family = AF_INET;
6629fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	((struct sockaddr_in *)addr)->sin_addr.s_addr = ((BW_UDPinfo_t *)lowmem_buffer)->localAddr.s_addr;
6639fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	((struct sockaddr_in *)addr)->sin_port = htons(((BW_UDPinfo_t *)lowmem_buffer)->localPort);
6649fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
6659fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	return 0;
6669fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
6679fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
6689fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream//=============================================================================
6699fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
6709fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamint BW_GetNameFromAddr (struct qsockaddr *addr, char *name)
6719fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
6729fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	Q_strcpy(name, BW_AddrToString(addr));
6739fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	return 0;
6749fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
6759fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
6769fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream///=============================================================================
6779fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
6789fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamint BW_GetAddrFromName (char *name, struct qsockaddr *hostaddr)
6799fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
6809fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	char buff[MAXHOSTNAMELEN];
6819fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	char *b;
6829fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	int addr;
6839fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	int num;
6849fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	int mask;
6859fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	int run;
6869fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	int port;
6879fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
6889fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (name[0] < '0' || name[0] > '9')
6899fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return -1;
6909fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
6919fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	buff[0] = '.';
6929fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	b = buff;
6939fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	Q_strcpy(buff+1, name);
6949fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (buff[1] == '.')
6959fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		b++;
6969fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
6979fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	addr = 0;
6989fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	mask = -1;
6999fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	while (*b == '.')
7009fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
7019fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		b++;
7029fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		num = 0;
7039fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		run = 0;
7049fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		while (!( *b < '0' || *b > '9'))
7059fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		{
7069fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		  num = num*10 + *b++ - '0';
7079fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		  if (++run > 3)
7089fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		  	return -1;
7099fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		}
7109fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		if ((*b < '0' || *b > '9') && *b != '.' && *b != ':' && *b != 0)
7119fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			return -1;
7129fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		if (num < 0 || num > 255)
7139fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			return -1;
7149fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		mask<<=8;
7159fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		addr = (addr<<8) + num;
7169fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
7179fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	addr = htonl(addr);
7189fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	mask = htonl(mask);
7199fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
7209fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (*b++ == ':')
7219fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		port = Q_atoi(b);
7229fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	else
7239fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		port = net_hostport;
7249fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
7259fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	hostaddr->sa_family = AF_INET;
7269fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	((struct sockaddr_in *)hostaddr)->sin_port = htons((short)port);
7279fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	((struct sockaddr_in *)hostaddr)->sin_addr.s_addr =
7289fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	((ethdevinfo.inetAddr & mask) | addr);
7299fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
7309fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	return 0;
7319fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
7329fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
7339fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream//=============================================================================
7349fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
7359fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamint BW_AddrCompare (struct qsockaddr *addr1, struct qsockaddr *addr2)
7369fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
7379fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (addr1->sa_family != addr2->sa_family)
7389fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return -1;
7399fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
7409fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (((struct sockaddr_in *)addr1)->sin_addr.s_addr != ((struct sockaddr_in *)addr2)->sin_addr.s_addr)
7419fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return -1;
7429fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
7439fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (((struct sockaddr_in *)addr1)->sin_port != ((struct sockaddr_in *)addr2)->sin_port)
7449fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return 1;
7459fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
7469fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	return 0;
7479fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
7489fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
7499fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream//=============================================================================
7509fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
7519fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamint BW_GetSocketPort (struct qsockaddr *addr)
7529fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
7539fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	return ntohs(((struct sockaddr_in *)addr)->sin_port);
7549fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
7559fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
7569fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
7579fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamint BW_SetSocketPort (struct qsockaddr *addr, int port)
7589fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
7599fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	((struct sockaddr_in *)addr)->sin_port = htons(port);
7609fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	return 0;
7619fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
7629fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
7639fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream//=============================================================================
764