⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wsockdos.c

📁 Libnet is a cross-platform library aimed at game developers. It has an abstract high level API, whic
💻 C
📖 第 1 页 / 共 3 页
字号:
/*---------------------------------------------------------------- * wsock.c - Winsock in DOS driver for libnet *---------------------------------------------------------------- *  libnet is (c) Copyright Chad Catlett and George Foot 1997-1998 * *  Please look in `docs' for details, documentation and *  distribution conditions. */#include "platdefs.h"/* If we can use the Winsock from DOS, do so.  Otherwise, dummy driver... */#ifdef __USE_REAL_WSOCK_DOS__#include <assert.h>#include <ctype.h>#include <dpmi.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/farptr.h>#include <sys/segments.h>#include <time.h>#include <netinet/in.h>#include "wsockdos.h"extern int __libnet_internal_wsockdos__dns_lookup (const char *, int, void *);/*------------------------------------------------ VxD interface code */#define VxdLdr_DeviceID 0x0027#define VxdLdr_LoadDevice 1#define VxdLdr_UnLoadDevice 2static int VxdLdrEntry [2] = {0, 0};  /* VxD loader/unloader 16 bit PM entry */static void VxdGetEntry (int *Entry, int ID){	int dummy;	asm ("\		pushl   %%es            \n\		movw    %%di, %%es      \n\		int     $0x2f           \n\		movl    $0, %%ecx       \n\		movw    %%es, %%cx      \n\		popl    %%es            "	:		"=a" (dummy),		"=c" (Entry [1]),		"=D" (Entry [0])	:		"a" (0x1684),		"b" (ID),		"D" (0)	:		"%edx"	);}static void VxdLdrInit (void){	VxdGetEntry (VxdLdrEntry, VxdLdr_DeviceID);}static int VxdLdrLoadDevice (char Device []){	int Error;	__dpmi_meminfo _dev;	int dev;	if (VxdLdrEntry [1] == 0) VxdLdrInit ();	if (VxdLdrEntry [1] == 0) return -1;	_dev.handle = 0;	_dev.size = strlen (Device) + 1;	_dev.address = 0;	__dpmi_allocate_memory (&_dev);	dev = __dpmi_allocate_ldt_descriptors (1);	__dpmi_set_segment_base_address (dev, _dev.address);	__dpmi_set_segment_limit (dev, _dev.size);	_farpokex (dev, 0, Device, _dev.size);	asm ("\		pushl   %%ds               \n\		movw    %%cx, %%ds         \n\		lcall  *%%cs:_VxdLdrEntry  \n\		setc    %%al               \n\		movzbl  %%al, %%eax        \n\		popl    %%ds"	:		"=a" (Error)	:		"a" (VxdLdr_LoadDevice),		"c" (dev),		"d" (0)	);	__dpmi_free_ldt_descriptor (dev);	__dpmi_free_memory (_dev.handle);	return Error;}static int VxdLdrUnLoadDevice (char Device []){	int Error;	__dpmi_meminfo _dev;	int dev;	if (VxdLdrEntry [1] == 0) VxdLdrInit ();	if (VxdLdrEntry [1] == 0) return -1;	_dev.handle = 0;	_dev.size = strlen (Device) + 1;	_dev.address = 0;	__dpmi_allocate_memory (&_dev);	dev = __dpmi_allocate_ldt_descriptors (1);	__dpmi_set_segment_base_address (dev, _dev.address);	__dpmi_set_segment_limit (dev, _dev.size);	_farpokex (dev, 0, Device, _dev.size);	asm ("\		pushl   %%ds               \n\		movw    %%cx, %%ds         \n\		lcall  *%%cs:_VxdLdrEntry  \n\		setc    %%al               \n\		movzbl  %%al, %%eax        \n\		popl    %%ds"	:		"=a" (Error)	:		"a" (VxdLdr_UnLoadDevice),		"c" (dev),		"d" (0)	);	__dpmi_free_ldt_descriptor (dev);	__dpmi_free_memory (_dev.handle);	return Error;}/*------------------------------------------------ Interface to WSOCK.VXD */static __dpmi_meminfo _SocketP;         /* 64k selector for parameters */static int SocketP;static __dpmi_meminfo _SocketD;         /* 64k selector for data */static int SocketD;static int last_error = 0;              /* last error code from VxD function */static int WSockEntry  [2] = {0, 0};    /* wsock.vxd 16 bit PM entry */static int call_vxd(int func){	int error;	asm ("\		pushl   %%es                    \n\		pushl   %%ecx                   \n\		popl    %%es                    \n\		lcall  *_WSockEntry             \n\		andl    $0x0000ffff, %%eax      \n\		popl    %%es"	:		"=a" (error)	:		"a" (func),		"b" (0),		"c" (SocketP)	);	return error;}static int handle_error(int error){	if (error && (error != 65535)) {		last_error = error;		return SOCKET_ERROR;	} else		return 0;}/* Semi-standard socket functions (some winsock-style rather than Berkeley) */static SOCKET accept (SOCKET s, struct sockaddr *addr, int *addrlen){	int error;	int AddressLength,AddressPointer;	SOCKET t;	if (addrlen)		AddressLength = *addrlen;	else		AddressLength = 0;	if (addr)		AddressPointer = (SocketP << 16) + (7 * 4);	else		AddressPointer = 0;	_farpokel (SocketP, 0 * 4, AddressPointer);             /* Address */	_farpokel (SocketP, 1 * 4, s);                          /* Listening Socket */	_farpokel (SocketP, 2 * 4, 0);                          /* Connected Socket */	_farpokel (SocketP, 3 * 4, AddressLength);              /* Address Length */	_farpokel (SocketP, 4 * 4, 0);                          /* Connected Socket Handle */	_farpokel (SocketP, 5 * 4, 0);                          /* Apc Routing */	_farpokel (SocketP, 6 * 4, 0);                          /* Apc Context */	error = call_vxd(WSOCK_ACCEPT_CMD);	if (addr&&addrlen)		_farpeekx (SocketP, 7 * 4, addr, *addrlen);            // should also update *addrlen	t = _farpeekl (SocketP, 2 * 4);	if (!error)		return t;	else {		handle_error(error);		return INVALID_SOCKET;	}}static int bind (SOCKET s, const struct sockaddr *name, int namelen){	int error;	_farpokel (SocketP, 0 * 4, (SocketP << 16) + (5 * 4));      /* Address */	_farpokel (SocketP, 1 * 4, s);                              /* Socket */	_farpokel (SocketP, 2 * 4, namelen);                        /* Address Length */	_farpokel (SocketP, 3 * 4, 0);                              /* Apc Routine */	_farpokel (SocketP, 4 * 4, 0);                              /* Apc Context */	_farpokex (SocketP, 5 * 4, name, namelen);	error = call_vxd(WSOCK_BIND_CMD);	return handle_error(error);}static int closesocket (SOCKET s){	int error;	_farpokel (SocketP, 0 * 4, s);	error = call_vxd(WSOCK_CLOSESOCKET_CMD);	return handle_error(error);}static int connect (SOCKET s, const struct sockaddr *name, int namelen){	int error;	_farpokel (SocketP, 0 * 4, (SocketP << 16) + (5 * 4));      // Address	_farpokel (SocketP, 1 * 4, s);                              // Socket	_farpokel (SocketP, 2 * 4, namelen);                        // Address Length	_farpokel (SocketP, 3 * 4, 0);                              // Apc Routine	_farpokel (SocketP, 4 * 4, 0);                              // Apc Context	_farpokex (SocketP, 5 * 4, name, namelen);	error = call_vxd(WSOCK_CONNECT_CMD);	return handle_error(error);}static int getpeername (SOCKET s, struct sockaddr *name, int *namelen){	int error;	_farpokel (SocketP, 0 * 4, (SocketP << 16) + (3 * 4));      /* Address */	_farpokel (SocketP, 1 * 4, s);                              /* Socket */	_farpokel (SocketP, 2 * 4, *namelen);                       /* Address Length */	error = call_vxd(WSOCK_GETPEERNAME_CMD);	_farpeekx (SocketP, 3 * 4, name, *namelen);	return handle_error(error);}static int getsockname (SOCKET s, struct sockaddr *name, int *namelen){	int error;	_farpokel (SocketP, 0 * 4, (SocketP << 16) + (3 * 4));      /* Address */	_farpokel (SocketP, 1 * 4, s);                              /* Socket */	_farpokel (SocketP, 2 * 4, *namelen);                       /* Address Length */	error = call_vxd(WSOCK_GETSOCKNAME_CMD);	_farpeekx (SocketP, 3 * 4, name, *namelen);	return handle_error(error);}static int getsockopt (SOCKET s, int level, int optname, char *optval, int *optlen){	int error;	_farpokel (SocketP, 0 * 4, (SocketP << 16) + (6 * 4));      /* Value */	_farpokel (SocketP, 1 * 4, s);                              /* Socket */	_farpokel (SocketP, 2 * 4, level);                          /* Option Level */	_farpokel (SocketP, 3 * 4, optname);                        /* Option Name */	_farpokel (SocketP, 4 * 4, *optlen);                        /* Value Length */	_farpokel (SocketP, 5 * 4, 0);                              /* Int Value */	error = call_vxd (WSOCK_GETSOCKOPT_CMD);	if (*optlen == 4)		*((int *) optval) = _farpeekl (SocketP, 5 * 4);	else		_farpeekx (SocketP, 6 * 4, optval, *optlen);	return handle_error(error);}static unsigned long inet_addr (const char *cp) {	unsigned int a[4] = { 0 };	int i = 0, error = 0;	const char *s = cp;	do {		if (!isdigit (*s))			error = 1;		else {			do {				a[i] = a[i] * 10 + (*s - '0');				s++;			} while (isdigit (*s));			if (*s == '.') {				if ((i == 3) || (a[i] > 255)) error = 1;				s++;				i++;			}		}	} while ((*s) && (!error));	if (error) return INADDR_NONE;	switch (i) {		case 0:			return a[0];			break;		case 1:			if (a[1] >= (1<<24)) return INADDR_NONE;			return (a[0] << 24) + a[1];			break;		case 2:			if (a[2] >= (1<<16)) return INADDR_NONE;			return (a[0] << 24) + (a[1] << 16) + a[2];			break;		case 3:			if (a[3] >= (1<<8)) return INADDR_NONE;			return (a[0] << 24) + (a[1] << 16) + (a[2] << 8) + a[3];			break;	}	return INADDR_NONE;}static char inet_ntoa_buffer[32] = { 0 };static void write_number (unsigned int num, char **where) {	if (num >= 10) write_number (num/10, where);	*((*where)++) = '0' + (num % 10);}static char *inet_ntoa (struct in_addr in) {	char *chp = inet_ntoa_buffer;	unsigned char *v = (unsigned char *)&in.s_addr;	write_number (v[3], &chp);	*chp++ = '.';	write_number (v[2], &chp);	*chp++ = '.';	write_number (v[1], &chp);	*chp++ = '.';	write_number (v[0], &chp);	*chp++ = 0;	return inet_ntoa_buffer;}static int ioctlsocket (SOCKET s, long cmd, u_long *argp){	int error;	int size;	_farpokel (SocketP, 0 * 4, s);                        /* Socket */	_farpokel (SocketP, 1 * 4, cmd);                      /* Command */	_farpokel (SocketP, 2 * 4, *argp);                    /* Parameter */	error = call_vxd (WSOCK_IOCTLSOCKET_CMD);	switch (cmd) {		case FIONBIO:		case FIONREAD:			size=4;			break;		case SIOCATMARK:			size=1;			break;		default:			size=0;	}	_farpeekx (SocketP, 2 * 4, argp, size);	return handle_error(error);}static int listen(SOCKET s, int backlog){	_farpokel (SocketP, 0 * 4, s);                      /* Socket */	_farpokel (SocketP, 1 * 4, backlog);                /* Backlog */	return handle_error(call_vxd(WSOCK_LISTEN_CMD));}static int recvfrom (SOCKET s, char *buf, int len, int flags, struct sockaddr *from, int *fromlen){	int error;	int AddressPointer, AddressLength;	if (from) {		if (fromlen)			AddressLength=*fromlen;		else			AddressLength=0;		AddressPointer = (SocketP << 16) + (10 * 4);	} else {		AddressPointer = 0;		AddressLength  = 0;	}	_farpokel (SocketP, 0 * 4, SocketD << 16);              /* Buffer */	_farpokel (SocketP, 1 * 4, AddressPointer);             /* Address */	_farpokel (SocketP, 2 * 4, s);                          /* Socket */	_farpokel (SocketP, 3 * 4, len);                        /* Buffer Length */	_farpokel (SocketP, 4 * 4, flags);                      /* Flags */	_farpokel (SocketP, 5 * 4, AddressLength);              /* Address Length */	_farpokel (SocketP, 6 * 4, 0);                          /* Bytes Received */	_farpokel (SocketP, 7 * 4, 0);                          /* Apc Routine */	_farpokel (SocketP, 8 * 4, 0);                          /* Apc Context */	_farpokel (SocketP, 9 * 4, 0);                          /* Timeout */	error = call_vxd (WSOCK_RECV_CMD);	if (from) _farpeekx (SocketP, 10 * 4, from, AddressLength);	_farpeekx (SocketD, 0, buf, len);	if (error==0)		return _farpeekl (SocketP, 6 * 4);	else		return handle_error(error);}static int recv (SOCKET s, char *buf, int len, int flags){	return recvfrom(s,buf,len,flags,0,0);}static int sendto (SOCKET s, const char *buf, int len, int flags, const struct sockaddr *to, int tolen){	int error;	int AddressPointer, AddressLength;	if (to) {		AddressPointer = (SocketP << 16) + (10 * 4);		AddressLength  = tolen;	} else {		AddressPointer = 0;		AddressLength  = 0;	}	_farpokel (SocketP, 0 * 4, SocketD << 16);                  /* Buffer */	_farpokel (SocketP, 1 * 4, AddressPointer);                 /* Address */	_farpokel (SocketP, 2 * 4, s);                              /* Socket */	_farpokel (SocketP, 3 * 4, len);                            /* Buffer Length */	_farpokel (SocketP, 4 * 4, flags);                          /* Flags */	_farpokel (SocketP, 5 * 4, AddressLength);                  /* Address Length */	_farpokel (SocketP, 6 * 4, 0);                              /* Bytes Sent */	_farpokel (SocketP, 7 * 4, 0);                              /* Apc Routine */	_farpokel (SocketP, 8 * 4, 0);                              /* Apc Context */	_farpokel (SocketP, 9 * 4, 0);                              /* Timeout */	if (to) _farpokex (SocketP, 10 * 4, to, tolen);	_farpokex (SocketD, 0, buf, len);	error = call_vxd (WSOCK_SEND_CMD);	if (error==0)		return _farpeekl (SocketP, 6 * 4);	else		return handle_error(error);}static int send (SOCKET s, const char *buf, int len, int flags){	return sendto(s,buf,len,flags,0,0);}static int setsockopt (SOCKET s, int level, int optname, const char *optval, int optlen){	int error;	_farpokel (SocketP, 0 * 4, (SocketP << 16) + (6 * 4));      /* Value */	_farpokel (SocketP, 1 * 4, s);                              /* Socket */	_farpokel (SocketP, 2 * 4, level);                          /* Option Level */	_farpokel (SocketP, 3 * 4, optname);                        /* Option Name */	_farpokel (SocketP, 4 * 4, optlen);                         /* Value Length */	_farpokel (SocketP, 5 * 4, *((int *) optval));              /* Int Value */	_farpokex (SocketP, 6 * 4, optval, optlen);	error = call_vxd (WSOCK_SETSOCKOPT_CMD);	return handle_error(error);}static int shutdown (SOCKET s, int how){	_farpokel (SocketP, 0 * 4, s);                              /* Socket */	_farpokel (SocketP, 1 * 4, how);                            /* How */	return handle_error(call_vxd(WSOCK_SHUTDOWN_CMD));}static SOCKET socket (int af, int type, int protocol){	SOCKET s;	int error;	_farpokel (SocketP, 0 * 4, af);                             /* Address Family */	_farpokel (SocketP, 1 * 4, type);                           /* Socket Type */	_farpokel (SocketP, 2 * 4, protocol);                       /* Protocol */	_farpokel (SocketP, 3 * 4, 0);                              /* New Socket */	_farpokel (SocketP, 4 * 4, 0);                              /* New Socket Handle */	error = call_vxd (WSOCK_SOCKET_CMD);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -