📄 wsockdos.c
字号:
/*---------------------------------------------------------------- * 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 + -