1
0
mirror of https://github.com/solemnwarning/ipxwrapper synced 2024-12-30 16:45:37 +01:00

Imported current tree into SVN

This commit is contained in:
Daniel Collins 2008-12-09 21:36:07 +00:00
commit 4d28856065
13 changed files with 1829 additions and 0 deletions

63
Makefile Normal file
View File

@ -0,0 +1,63 @@
# ipxwrapper - Makefile
# Copyright (C) 2008 Daniel Collins <solemnwarning@solemnwarning.net>
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 as published by
# the Free Software Foundation.
#
# 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 the Free Software Foundation, Inc., 51
# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
CFLAGS := -Wall
IPXWRAPPER_DEPS := src/ipxwrapper.o src/winsock.o src/ipxwrapper_stubs.o src/ipxwrapper.def
WSOCK32_DEPS := src/stubdll.o src/wsock32_stubs.o src/wsock32.def
MSWSOCK_DEPS := src/stubdll.o src/mswsock_stubs.o src/mswsock.def
all: ipxwrapper.dll wsock32.dll mswsock.dll
clean:
rm -f src/*.o
rm -f src/*_stubs.c
ipxwrapper.dll: $(IPXWRAPPER_DEPS)
$(CC) $(CFLAGS) -Wl,--enable-stdcall-fixup -shared -o ipxwrapper.dll $(IPXWRAPPER_DEPS) -liphlpapi
wsock32.dll: $(WSOCK32_DEPS)
$(CC) $(CFLAGS) -Wl,--enable-stdcall-fixup -shared -o wsock32.dll $(WSOCK32_DEPS)
mswsock.dll: $(MSWSOCK_DEPS)
$(CC) $(CFLAGS) -Wl,--enable-stdcall-fixup -shared -o mswsock.dll $(MSWSOCK_DEPS)
src/ipxwrapper.o: src/ipxwrapper.c src/ipxwrapper.h
$(CC) $(CFLAGS) -c -o src/ipxwrapper.o src/ipxwrapper.c
src/winsock.o: src/winsock.c src/ipxwrapper.h
$(CC) $(CFLAGS) -c -o src/winsock.o src/winsock.c
src/ipxwrapper_stubs.o: src/ipxwrapper_stubs.c
$(CC) $(CFLAGS) -c -o src/ipxwrapper_stubs.o src/ipxwrapper_stubs.c
src/ipxwrapper_stubs.c: src/ipxwrapper_stubs.txt
perl mkstubs.pl src/ipxwrapper_stubs.txt src/ipxwrapper_stubs.c
src/stubdll.o: src/stubdll.c
$(CC) $(CFLAGS) -c -o src/stubdll.o src/stubdll.c
src/wsock32_stubs.o: src/wsock32_stubs.c
$(CC) $(CFLAGS) -c -o src/wsock32_stubs.o src/wsock32_stubs.c
src/wsock32_stubs.c: src/wsock32_stubs.txt
perl mkstubs.pl src/wsock32_stubs.txt src/wsock32_stubs.c wsock32.dll
src/mswsock_stubs.o: src/mswsock_stubs.c
$(CC) $(CFLAGS) -c -o src/mswsock_stubs.o src/mswsock_stubs.c
src/mswsock_stubs.c: src/mswsock_stubs.txt
perl mkstubs.pl src/mswsock_stubs.txt src/mswsock_stubs.c mswsock.dll

109
mkstubs.pl Normal file
View File

@ -0,0 +1,109 @@
# ipxwrapper - Create stub functions from headers
# Copyright (C) 2008 Daniel Collins <solemnwarning@solemnwarning.net>
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 as published by
# the Free Software Foundation.
#
# 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 the Free Software Foundation, Inc., 51
# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
use strict;
use warnings;
if(@ARGV != 2 && @ARGV != 3) {
print STDERR "Usage: mkdll.pl <input header> <output code> [<dll name>]\n";
exit(1);
}
open(STUBS, "<".$ARGV[0]) or die("Cannot open ".$ARGV[0].": $!");
open(CODE, ">".$ARGV[1]) or die("Cannot open ".$ARGV[1].": $!");
print CODE <<EOF;
#include <windows.h>
#include <winsock2.h>
#include <mswsock.h>
#include <nspapi.h>
#include <ws2spi.h>
void *find_sym(char const *symbol);
EOF
if(@ARGV == 3) {
print CODE "char const *dllname = \"".$ARGV[2]."\";\n";
}
foreach my $line(<STUBS>) {
$line =~ s/[\r\n;]//g;
$line =~ s/\/\*.*\*\///g;
if($line eq "") {
next;
}
my $type = "";
my $func = "";
my $args = "";
foreach my $word(split(/ /, $line)) {
if($word =~ /\w+\(/) {
if($func ne "") {
$type .= " $func($args";
}
($func, $args) = split(/\(/, $word, 2);
next;
}
if($args ne "") {
$args .= " $word";
}else{
if($type ne "") {
$type .= " ";
}
$type .= $word;
}
}
$args =~ s/\)$//;
my $argdefs = "void";
my $argnames = "";
my $count = 0;
if($args ne "void") {
foreach my $arg(split(/,/, $args)) {
if($count == 0) {
$argdefs = "$arg arg$count";
$argnames = "arg$count";
}else{
$argdefs .= ", $arg arg$count";
$argnames .= ", arg$count";
}
$count++;
}
}
my $symbol = $func;
$symbol =~ s/^r_//;
print CODE "\n$type $func($argdefs) {\n";
print CODE "\tstatic $type (*real_$func)($args) = NULL;\n";
print CODE "\tif(!real_$func) {\n";
print CODE "\t\treal_$func = find_sym(\"$symbol\");\n";
print CODE "\t}\n";
print CODE "\treturn real_$func($argnames);\n";
print CODE "}\n";
}
close(CODE);
close(STUBS);

428
src/ipxwrapper.c Normal file
View File

@ -0,0 +1,428 @@
/* ipxwrapper - Library functions
* Copyright (C) 2008 Daniel Collins <solemnwarning@solemnwarning.net>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*
* 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 the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <windows.h>
#include <winsock2.h>
#include <wsipx.h>
#include <nspapi.h>
#include <iphlpapi.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdint.h>
#include "ipxwrapper.h"
#include "ipxwrapper_stubs.txt"
#define DLL_UNLOAD(dll) \
if(dll) {\
FreeModule(dll);\
dll = NULL;\
}
ipx_socket *sockets = NULL;
ipx_nic *nics = NULL;
ipx_host *hosts = NULL;
SOCKET net_fd = -1;
HMODULE winsock2_dll = NULL;
HMODULE mswsock_dll = NULL;
HMODULE wsock32_dll = NULL;
static FILE *debug_fh = NULL;
static HANDLE mutex = NULL;
static HANDLE router_thread = NULL;
static DWORD router_tid = 0;
static int mutex_locked = 0;
static HMODULE load_sysdll(char const *name);
static int init_router(void);
static DWORD WINAPI router_main(LPVOID argp);
static void add_host(unsigned char *hwaddr, uint32_t ipaddr);
BOOL WINAPI DllMain(HINSTANCE me, DWORD why, LPVOID res) {
if(why == DLL_PROCESS_ATTACH) {
#ifdef DEBUG
debug_fh = fopen(DEBUG, "w");
#endif
winsock2_dll = load_sysdll("ws2_32.dll");
mswsock_dll = load_sysdll("mswsock.dll");
wsock32_dll = load_sysdll("wsock32.dll");
if(!winsock2_dll || !mswsock_dll || !wsock32_dll) {
return FALSE;
}
IP_ADAPTER_INFO *ifroot = get_nics();
IP_ADAPTER_INFO *ifptr = ifroot;
ipx_nic *enic = NULL;
while(ifptr) {
ipx_nic *nnic = malloc(sizeof(ipx_nic));
if(!nnic) {
return FALSE;
}
INIT_NIC(nnic);
nnic->ipaddr = ntohl(inet_addr(ifptr->IpAddressList.IpAddress.String));
nnic->netmask = ntohl(inet_addr(ifptr->IpAddressList.IpMask.String));
nnic->bcast = nnic->ipaddr | ~nnic->netmask;
nnic->start = (nnic->ipaddr & nnic->netmask) | 1;
nnic->end = (nnic->ipaddr & nnic->netmask) | (~nnic->netmask & ~1);
memcpy(nnic->hwaddr, ifptr->Address, 6);
if(enic) {
enic->next = nnic;
}else{
enic = nics = nnic;
}
ifptr = ifptr->Next;
}
free(ifroot);
mutex = CreateMutex(NULL, FALSE, NULL);
if(!mutex) {
debug("Failed to create mutex");
return FALSE;
}
WSADATA wsdata;
int err = WSAStartup(MAKEWORD(1,1), &wsdata);
if(err) {
debug("Failed to initialize winsock: %s", w32_error(err));
return FALSE;
}
if(!init_router()) {
return FALSE;
}
}
if(why == DLL_PROCESS_DETACH) {
if(router_thread && GetCurrentThreadId() != router_tid) {
TerminateThread(router_thread, 0);
router_thread = NULL;
}
if(net_fd >= 0) {
closesocket(net_fd);
net_fd = -1;
}
if(mutex) {
CloseHandle(mutex);
mutex = NULL;
}
WSACleanup();
DLL_UNLOAD(winsock2_dll);
DLL_UNLOAD(mswsock_dll);
DLL_UNLOAD(wsock32_dll);
}
return TRUE;
}
void *find_sym(char const *symbol) {
void *addr = GetProcAddress(winsock2_dll, symbol);
if(!addr) {
addr = GetProcAddress(mswsock_dll, symbol);
}
if(!addr) {
addr = GetProcAddress(wsock32_dll, symbol);
}
if(!addr) {
debug("Unknown symbol: %s", symbol);
abort();
}
return addr;
}
void debug(char const *fmt, ...) {
char msg[1024];
va_list argv;
if(debug_fh) {
va_start(argv, fmt);
vsnprintf(msg, 1024, fmt, argv);
va_end(argv);
fprintf(debug_fh, "%s\n", msg);
fflush(debug_fh);
}
}
/* Lock the mutex and search the sockets list for an ipx_socket structure with
* the requested fd, if no matching fd is found, unlock the mutex
*/
ipx_socket *get_socket(SOCKET fd) {
lock_mutex();
ipx_socket *ptr = sockets;
while(ptr) {
if(ptr->fd == fd) {
break;
}
ptr = ptr->next;
}
if(!ptr) {
unlock_mutex();
}
return ptr;
}
/* Lock the mutex */
void lock_mutex(void) {
if(mutex_locked) {
return;
}
WaitForSingleObject(mutex, INFINITE);
mutex_locked++;
}
/* Unlock the mutex */
void unlock_mutex(void) {
mutex_locked = 0;
ReleaseMutex(mutex);
}
IP_ADAPTER_INFO *get_nics(void) {
IP_ADAPTER_INFO *buf, tbuf;
ULONG bufsize = sizeof(IP_ADAPTER_INFO);
int rval = GetAdaptersInfo(&tbuf, &bufsize);
if(rval != ERROR_SUCCESS) {
WSASetLastError(rval);
return NULL;
}
buf = malloc(bufsize);
if(!buf) {
WSASetLastError(ERROR_OUTOFMEMORY);
return NULL;
}
rval = GetAdaptersInfo(buf, &bufsize);
if(rval != ERROR_SUCCESS) {
WSASetLastError(rval);
free(buf);
return NULL;
}
return buf;
}
/* Load a system DLL */
static HMODULE load_sysdll(char const *name) {
char sysdir[1024], path[1024];
HMODULE ret = NULL;
GetSystemDirectory(path, 1024);
snprintf(path, 1024, "%s\\%s", sysdir, name);
ret = LoadLibrary(path);
if(!ret) {
debug("Error loading %s: %s", path, w32_error(GetLastError()));
}
return ret;
}
/* Initialize and start the router thread */
static int init_router(void) {
net_fd = socket(AF_INET, SOCK_DGRAM, 0);
if(net_fd == -1) {
debug("Failed to create listener socket: %s", w32_error(WSAGetLastError()));
return 0;
}
struct sockaddr_in bind_addr;
bind_addr.sin_family = AF_INET;
bind_addr.sin_addr.s_addr = inet_addr("0.0.0.0");
bind_addr.sin_port = htons(PORT);
if(bind(net_fd, (struct sockaddr*)&bind_addr, sizeof(bind_addr)) == -1) {
debug("Failed to bind listener socket");
return 0;
}
BOOL broadcast = TRUE;
int bufsize = 524288; /* 512KiB */
setsockopt(net_fd, SOL_SOCKET, SO_BROADCAST, (char*)&broadcast, sizeof(BOOL));
setsockopt(net_fd, SOL_SOCKET, SO_RCVBUF, (char*)&bufsize, sizeof(int));
setsockopt(net_fd, SOL_SOCKET, SO_SNDBUF, (char*)&bufsize, sizeof(int));
/* Memory leak, ah well... */
void *pbuf = malloc(PACKET_BUF_SIZE);
if(!pbuf) {
debug("Not enough memory for packet buffer (64KiB)");
return 0;
}
router_thread = CreateThread(NULL, 0, &router_main, pbuf, 0, &router_tid);
if(!router_thread) {
debug("Failed to create router thread");
return 0;
}
return 1;
}
/* Router thread main function
*
* The router thread recieves packets from the listening port and forwards them
* to the UDP sockets which emulate IPX.
*/
static DWORD WINAPI router_main(LPVOID buf) {
ipx_packet *packet = buf;
int addrlen, rval, sval;
unsigned char f6[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
struct sockaddr_in addr;
ipx_socket *sockptr;
while(1) {
addrlen = sizeof(addr);
rval = recvfrom(net_fd, (char*)packet, PACKET_BUF_SIZE, 0, (struct sockaddr*)&addr, &addrlen);
if(rval <= 0) {
debug("Error recieving packet: %s", w32_error(WSAGetLastError()));
continue;
}
if(rval < sizeof(ipx_packet)) {
debug("Recieved undersized packet, discarding");
continue;
}
packet->dest_socket = ntohs(packet->dest_socket);
packet->src_socket = ntohs(packet->src_socket);
packet->size = ntohs(packet->size);
/* Prevent buffer overflows */
if(packet->size > MAX_PACKET_SIZE) {
debug("Recieved oversized packet, discarding");
continue;
}
lock_mutex();
add_host(packet->src_node, ntohl(addr.sin_addr.s_addr));
for(sockptr = sockets; sockptr; sockptr = sockptr->next) {
if(
sockptr->flags & IPX_BOUND &&
sockptr->flags & IPX_RECV &&
packet->dest_socket == sockptr->socket &&
(
!(sockptr->flags & IPX_FILTER) ||
packet->ptype == sockptr->f_ptype
) && (
memcmp(packet->dest_net, sockptr->netnum, 4) == 0 ||
(
memcmp(packet->dest_net, f6, 4) == 0 &&
sockptr->flags & IPX_BROADCAST
)
) && (
memcmp(packet->dest_node, sockptr->nodenum, 6) == 0 ||
(
memcmp(packet->dest_node, f6, 6) == 0 &&
sockptr->flags & IPX_BROADCAST
)
)
) {
addrlen = sizeof(addr);
if(r_getsockname(sockptr->fd, (struct sockaddr*)&addr, &addrlen) == -1) {
continue;
}
sval = r_sendto(sockptr->fd, (char*)buf, rval, 0, (struct sockaddr*)&addr, addrlen);
if(sval == -1) {
debug("Error relaying packet: %s", w32_error(WSAGetLastError()));
}
}
}
unlock_mutex();
}
return 0;
}
/* Convert a windows error number to an error message */
char const *w32_error(DWORD errnum) {
static char buf[1024] = {'\0'};
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, errnum, 0, buf, 1023, NULL);
buf[strcspn(buf, "\r\n")] = '\0';
return buf;
}
/* Add a host to the hosts list */
static void add_host(unsigned char *hwaddr, uint32_t ipaddr) {
ipx_host *hptr = hosts;
while(hptr) {
if(memcmp(hptr->hwaddr, hwaddr, 6) == 0) {
hptr->ipaddr = ipaddr;
return;
}
hptr = hptr->next;
}
hptr = malloc(sizeof(ipx_host));
if(!hptr) {
debug("No memory for hosts list entry");
return;
}
INIT_HOST(hptr);
memcpy(hptr->hwaddr, hwaddr, 6);
hptr->ipaddr = ipaddr;
hptr->next = hosts;
hosts = hptr;
}
/* Search the hosts list */
ipx_host *find_host(unsigned char *hwaddr) {
ipx_host *hptr = hosts;
while(hptr) {
if(memcmp(hptr->hwaddr, hwaddr, 6) == 0) {
return hptr;
}
hptr = hptr->next;
}
return NULL;
}

15
src/ipxwrapper.def Normal file
View File

@ -0,0 +1,15 @@
LIBRARY IPXWRAPPER.dll
EXPORTS
bind
closesocket
getsockname
getsockopt
recv
recvfrom
sendto
setsockopt
shutdown
socket
EnumProtocolsA
EnumProtocolsW
WSARecvEx

159
src/ipxwrapper.h Normal file
View File

@ -0,0 +1,159 @@
/* ipxwrapper - Library header
* Copyright (C) 2008 Daniel Collins <solemnwarning@solemnwarning.net>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*
* 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 the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef IPXWRAPPER_H
#define IPXWRAPPER_H
#include <windows.h>
#include <winsock2.h>
#include <iphlpapi.h>
#include <stdint.h>
#define PORT 13579
#define DEBUG "ipxwrapper.log"
/* Maximum UDP data size is 65467, we use a smaller value to ensure we have
* plenty of space to play with for headers, etc
*/
#define MAX_PACKET_SIZE 63487
#define PACKET_BUF_SIZE 65536
#define IPX_FILTER (int)(1<<0)
#define IPX_BOUND (int)(1<<1)
#define IPX_BROADCAST (int)(1<<2)
#define IPX_SEND (int)(1<<3)
#define IPX_RECV (int)(1<<4)
#define INIT_SOCKET(ptr) \
(ptr)->fd = -1;\
(ptr)->flags = IPX_SEND | IPX_RECV;\
(ptr)->s_ptype = 0;\
(ptr)->f_ptype = 0;\
memset((ptr)->netnum, 0, 4);\
memset((ptr)->nodenum, 0, 6);\
(ptr)->socket = 0;\
(ptr)->next = NULL;
#define INIT_PACKET(ptr) \
(ptr)->ptype = 0;\
memset((ptr)->dest_net, 0, 4);\
memset((ptr)->dest_node, 0, 6);\
(ptr)->dest_socket = 0;\
memset((ptr)->src_net, 0, 4);\
memset((ptr)->src_node, 0, 6);\
(ptr)->src_socket = 0;\
(ptr)->size = 0;
#define INIT_NIC(ptr) \
(ptr)->ipaddr = 0;\
(ptr)->netmask = 0;\
(ptr)->bcast = 0;\
(ptr)->start = 0;\
(ptr)->end = 0;\
memset((ptr)->hwaddr, 0, 6);\
(ptr)->next = NULL;
#define INIT_HOST(ptr) \
memset((ptr)->hwaddr, 0, 6);\
(ptr)->ipaddr = 0;\
(ptr)->next = NULL;
#define RETURN(...) \
unlock_mutex();\
return __VA_ARGS__;
#define RETURN_WSA(errnum, ...) \
unlock_mutex();\
WSASetLastError(errnum);\
return __VA_ARGS__;
#define RETURN_ERR(errnum, ...) \
unlock_mutex();\
SetLastError(errnum);\
return __VA_ARGS__;
typedef struct ipx_socket ipx_socket;
typedef struct ipx_packet ipx_packet;
typedef struct ipx_nic ipx_nic;
typedef struct ipx_host ipx_host;
struct ipx_socket {
SOCKET fd;
int flags;
uint8_t s_ptype;
uint8_t f_ptype;
unsigned char netnum[4];
unsigned char nodenum[6];
uint16_t socket;
ipx_socket *next;
};
struct ipx_packet {
uint8_t ptype;
unsigned char dest_net[4];
unsigned char dest_node[6];
uint16_t dest_socket;
unsigned char src_net[4];
unsigned char src_node[6];
uint16_t src_socket;
uint16_t size;
char data[1];
} __attribute__((__packed__));
struct ipx_nic {
uint32_t ipaddr;
uint32_t netmask;
uint32_t bcast;
uint32_t start;
uint32_t end;
unsigned char hwaddr[6];
ipx_nic *next;
};
struct ipx_host {
unsigned char hwaddr[6];
uint32_t ipaddr;
ipx_host *next;
};
extern ipx_socket *sockets;
extern ipx_nic *nics;
extern ipx_host *hosts;
extern SOCKET net_fd;
extern HMODULE winsock2_dll;
extern HMODULE mswsock_dll;
extern HMODULE wsock32_dll;
void *find_sym(char const *sym);
void debug(char const *fmt, ...);
ipx_socket *get_socket(SOCKET fd);
void lock_mutex(void);
void unlock_mutex(void);
IP_ADAPTER_INFO *get_nics(void);
char const *w32_error(DWORD errnum);
ipx_host *find_host(unsigned char *hwaddr);
#endif /* !IPXWRAPPER_H */

27
src/ipxwrapper_stubs.txt Normal file
View File

@ -0,0 +1,27 @@
/* Stub functions will be generated for all functions declared here */
/* Declarations from MinGW headers */
unsigned long PASCAL inet_addr(const char*);
int PASCAL WSAStartup(WORD,LPWSADATA);
int PASCAL WSACleanup(void);
void PASCAL WSASetLastError(int);
int PASCAL WSAGetLastError(void);
u_long PASCAL htonl(u_long);
u_long PASCAL ntohl(u_long);
u_short PASCAL htons(u_short);
u_short PASCAL ntohs(u_short);
/* Declarations from the win32 SDK and MSDN */
INT APIENTRY r_EnumProtocolsA(LPINT,LPVOID,LPDWORD);
INT APIENTRY r_EnumProtocolsW(LPINT,LPVOID,LPDWORD);
int PASCAL FAR r_WSARecvEx(SOCKET,char*,int,int*);
int WSAAPI r_bind(SOCKET,const struct sockaddr*,int);
int WSAAPI r_closesocket(SOCKET);
int WSAAPI r_getsockname(SOCKET,struct sockaddr*,int*);
int WSAAPI r_getsockopt(SOCKET,int,int,char*,int*);
int WSAAPI r_recv(SOCKET,char*,int,int);
int WSAAPI r_recvfrom(SOCKET,char*,int,int,struct sockaddr*,int*);
int WSAAPI r_sendto(SOCKET,const char*,int,int,const struct sockaddr*,int);
int WSAAPI r_setsockopt(SOCKET,int,int,const char*,int);
int WSAAPI r_shutdown(SOCKET,int);
SOCKET WSAAPI r_socket(int,int,int);

23
src/mswsock.def Normal file
View File

@ -0,0 +1,23 @@
LIBRARY MSWSOCK.dll
EXPORTS
; ServiceMain @1
; SvchostPushServiceGlobals @2
AcceptEx @3
EnumProtocolsA @4
EnumProtocolsW @5
GetAcceptExSockaddrs @6
GetAddressByNameA @7
GetAddressByNameW @8
GetNameByTypeA @9
GetNameByTypeW @10
GetServiceA @11
GetServiceW @12
GetTypeByNameA @13
GetTypeByNameW @14
NSPStartup @17
SetServiceA @18
SetServiceW @19
TransmitFile @22
WSARecvEx @23
WSPStartup @24
sethostname @32

24
src/mswsock_stubs.txt Normal file
View File

@ -0,0 +1,24 @@
/* Stub functions will be generated for all functions declared here */
/* Declarations from MinGW headers */
BOOL PASCAL AcceptEx(SOCKET,SOCKET,PVOID,DWORD,DWORD,DWORD,LPDWORD,LPOVERLAPPED);
VOID PASCAL GetAcceptExSockaddrs(PVOID,DWORD,DWORD,DWORD,struct sockaddr**, LPINT, struct sockaddr**, LPINT);
INT WINAPI GetAddressByNameA(DWORD,LPGUID,LPSTR,LPINT,DWORD,LPSERVICE_ASYNC_INFO,LPVOID,LPDWORD,LPSTR,LPDWORD);
INT WINAPI GetAddressByNameW(DWORD,LPGUID,LPWSTR,LPINT,DWORD,LPSERVICE_ASYNC_INFO,LPVOID,LPDWORD,LPWSTR,LPDWORD);
INT WINAPI SetServiceA(DWORD,DWORD,DWORD,LPSERVICE_INFOA,LPSERVICE_ASYNC_INFO,LPDWORD);
INT WINAPI SetServiceW(DWORD,DWORD,DWORD,LPSERVICE_INFOW,LPSERVICE_ASYNC_INFO,LPDWORD);
BOOL PASCAL TransmitFile(SOCKET,HANDLE,DWORD,DWORD,LPOVERLAPPED,LPTRANSMIT_FILE_BUFFERS,DWORD);
/* Declarations from the win32 SDK and MSDN */
INT WSAAPI NSPStartup(LPGUID,LPNSP_ROUTINE);
INT APIENTRY GetNameByTypeA(IN LPGUID,IN OUT LPSTR,IN DWORD);
INT APIENTRY GetNameByTypeW(IN LPGUID,IN OUT LPWSTR,IN DWORD);
INT APIENTRY GetServiceA(DWORD, LPGUID, LPSTR,DWORD,LPVOID,LPDWORD,LPSERVICE_ASYNC_INFO);
INT APIENTRY GetServiceW(DWORD, LPGUID, LPWSTR,DWORD,LPVOID,LPDWORD,LPSERVICE_ASYNC_INFO);
INT APIENTRY GetTypeByNameA(LPSTR,LPGUID);
INT APIENTRY GetTypeByNameW(LPWSTR,LPGUID);
int WSPAPI WSPStartup(WORD,LPWSPDATA,LPWSAPROTOCOL_INFOW,WSPUPCALLTABLE,LPWSPPROC_TABLE);
int APIENTRY sethostname(char*,int);
INT APIENTRY EnumProtocolsA(LPINT,LPVOID,LPDWORD);
INT APIENTRY EnumProtocolsW(LPINT,LPVOID,LPDWORD);
int PASCAL FAR WSARecvEx(SOCKET,char*,int,int*);

93
src/stubdll.c Normal file
View File

@ -0,0 +1,93 @@
/* ipxwrapper - Stub DLL functions
* Copyright (C) 2008 Daniel Collins <solemnwarning@solemnwarning.net>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*
* 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 the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
static HMODULE ipxdll = NULL;
static HMODULE sysdll = NULL;
extern char const *dllname;
void *find_sym(char const *symbol);
void debug(char const *fmt, ...);
BOOL WINAPI DllMain(HINSTANCE me, DWORD why, LPVOID res) {
char sysdir[1024], path[1024];
if(why == DLL_PROCESS_ATTACH) {
GetSystemDirectory(sysdir, 1024);
snprintf(path, 1024, "%s\\%s", sysdir, dllname);
ipxdll = LoadLibrary("ipxwrapper.dll");
if(!ipxdll) {
return 0;
}
sysdll = LoadLibrary(path);
if(!sysdll) {
return 0;
}
}
if(why == DLL_PROCESS_DETACH) {
if(sysdll) {
FreeLibrary(sysdll);
sysdll = NULL;
}
if(ipxdll) {
FreeLibrary(ipxdll);
ipxdll = NULL;
}
}
return TRUE;
}
void *find_sym(char const *symbol) {
void *ptr = NULL;
if(!ptr) {
ptr = GetProcAddress(ipxdll, symbol);
}
if(!ptr) {
ptr = GetProcAddress(sysdll, symbol);
}
if(!ptr) {
debug("Missing symbol in %s: %s", dllname, symbol);
abort();
}
return ptr;
}
void debug(char const *fmt, ...) {
static void (*real_debug)(char const*,...) = NULL;
char msgbuf[1024];
va_list argv;
if(ipxdll && !real_debug) {
real_debug = (void*)GetProcAddress(ipxdll, "debug");
}
if(real_debug) {
va_start(argv, fmt);
vsnprintf(msgbuf, 1024, fmt, argv);
va_end(argv);
real_debug("%s", msgbuf);
}
}

637
src/winsock.c Normal file
View File

@ -0,0 +1,637 @@
/* ipxwrapper - Winsock functions
* Copyright (C) 2008 Daniel Collins <solemnwarning@solemnwarning.net>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*
* 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 the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <windows.h>
#include <winsock2.h>
#include <wsipx.h>
#include <mswsock.h>
#include <nspapi.h>
#include "winstuff.h"
#include "ipxwrapper.h"
#include "ipxwrapper_stubs.txt"
INT APIENTRY EnumProtocolsA(LPINT protocols, LPVOID buf, LPDWORD bsptr) {
int bufsize = *bsptr, rval, i, want_ipx = 0;
PROTOCOL_INFO *pinfo = buf;
rval = r_EnumProtocolsA(protocols, buf, bsptr);
if(rval == -1) {
return -1;
}
if(!protocols) {
want_ipx = 1;
}else{
for(i = 0; protocols[i]; i++) {
if(protocols[i] == NSPROTO_IPX) {
want_ipx = 1;
break;
}
}
}
if(want_ipx) {
for(i = 0; i < rval; i++) {
if(pinfo[i].iProtocol == NSPROTO_IPX) {
break;
}
}
if(i == rval) {
*bsptr += sizeof(PROTOCOL_INFO);
rval++;
}
if(*bsptr > bufsize) {
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return -1;
}
pinfo[i].dwServiceFlags = 5641;
pinfo[i].iAddressFamily = AF_IPX;
pinfo[i].iMaxSockAddr = 16;
pinfo[i].iMinSockAddr = 14;
pinfo[i].iSocketType = SOCK_DGRAM;
pinfo[i].iProtocol = NSPROTO_IPX;
pinfo[i].dwMessageSize = 576;
pinfo[i].lpProtocol = "IPX";
}
return rval;
}
INT APIENTRY EnumProtocolsW(LPINT protocols, LPVOID buf, LPDWORD bsptr) {
int bufsize = *bsptr, rval, i, want_ipx = 0;
PROTOCOL_INFO *pinfo = buf;
rval = r_EnumProtocolsW(protocols, buf, bsptr);
if(rval == -1) {
return -1;
}
if(!protocols) {
want_ipx = 1;
}else{
for(i = 0; protocols[i]; i++) {
if(protocols[i] == NSPROTO_IPX) {
want_ipx = 1;
break;
}
}
}
if(want_ipx) {
for(i = 0; i < rval; i++) {
if(pinfo[i].iProtocol == NSPROTO_IPX) {
break;
}
}
if(i == rval) {
*bsptr += sizeof(PROTOCOL_INFO);
rval++;
}
if(*bsptr > bufsize) {
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return -1;
}
pinfo[i].dwServiceFlags = 5641;
pinfo[i].iAddressFamily = AF_IPX;
pinfo[i].iMaxSockAddr = 16;
pinfo[i].iMinSockAddr = 14;
pinfo[i].iSocketType = SOCK_DGRAM;
pinfo[i].iProtocol = NSPROTO_IPX;
pinfo[i].dwMessageSize = 576;
pinfo[i].lpProtocol = (char*)L"IPX";
}
return rval;
}
int PASCAL WSARecvEx(SOCKET fd, char *buf, int len, int *flags) {
ipx_socket *ptr = get_socket(fd);
if(ptr) {
if(!(ptr->flags & IPX_BOUND)) {
RETURN_WSA(WSAEINVAL, -1);
}
struct ipx_packet *packet = malloc(PACKET_BUF_SIZE);
if(!packet) {
RETURN_WSA(ERROR_OUTOFMEMORY, -1);
}
int rval = r_WSARecvEx(fd, (char*)packet, PACKET_BUF_SIZE, flags);
if(rval == -1) {
RETURN(-1);
}
if(packet->size <= len) {
memcpy(buf, packet->data, packet->size);
len = packet->size;
free(packet);
*flags = 0;
RETURN(len);
}else{
memcpy(buf, packet->data, len);
len = packet->size;
free(packet);
*flags = MSG_PARTIAL;
RETURN(len);
}
}else{
RETURN(r_WSARecvEx(fd, buf, len, flags));
}
}
SOCKET WSAAPI socket(int af, int type, int protocol) {
debug("socket(%d, %d, %d)", af, type, protocol);
if(af == AF_IPX) {
ipx_socket *nsock = malloc(sizeof(ipx_socket));
if(!nsock) {
RETURN_WSA(ERROR_OUTOFMEMORY, -1);
}
INIT_SOCKET(nsock);
nsock->fd = r_socket(AF_INET, SOCK_DGRAM, 0);
if(nsock->fd == -1) {
debug("...failed: %s", w32_error(WSAGetLastError()));
free(nsock);
RETURN(-1);
}
if(protocol) {
nsock->s_ptype = NSPROTO_IPX - protocol;
}
lock_mutex();
nsock->next = sockets;
sockets = nsock;
debug("...success: fd=%d", nsock->fd);
RETURN(nsock->fd);
}else{
return r_socket(af, type, protocol);
}
}
int WSAAPI closesocket(SOCKET fd) {
debug("closesocket(%d)", fd);
if(r_closesocket(fd) == SOCKET_ERROR) {
debug("...failed");
RETURN(SOCKET_ERROR);
}
ipx_socket *ptr = get_socket(fd);
ipx_socket *pptr = sockets;
debug("...success");
if(ptr == sockets) {
sockets = ptr->next;
free(ptr);
}else{
while(ptr && pptr->next) {
if(ptr == pptr->next) {
pptr->next = ptr->next;
free(ptr);
}
pptr = pptr->next;
}
}
RETURN(0);
}
int WSAAPI bind(SOCKET fd, const struct sockaddr *addr, int addrlen) {
ipx_socket *ptr = get_socket(fd);
if(ptr) {
struct sockaddr_ipx *ipxaddr = (struct sockaddr_ipx*)addr;
debug(
"bind(%d, net=%hhx:%hhx:%hhx:%hhx node=%hhx:%hhx:%hhx:%hhx:%hhx:%hhx socket=%hu)", fd,
ipxaddr->sa_netnum[0],
ipxaddr->sa_netnum[1],
ipxaddr->sa_netnum[2],
ipxaddr->sa_netnum[3],
ipxaddr->sa_nodenum[0],
ipxaddr->sa_nodenum[1],
ipxaddr->sa_nodenum[2],
ipxaddr->sa_nodenum[3],
ipxaddr->sa_nodenum[4],
ipxaddr->sa_nodenum[5],
ntohs(ipxaddr->sa_socket)
);
struct sockaddr_in bind_addr;
bind_addr.sin_family = AF_INET;
bind_addr.sin_port = 0;
bind_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
int rval = r_bind(fd, (struct sockaddr*)&bind_addr, sizeof(bind_addr));
if(rval == 0) {
memcpy(ptr->netnum, ipxaddr->sa_netnum, 4);
ipx_nic *nic = nics;
int first = 1;
while(nic) {
if(first || memcmp(ipxaddr->sa_nodenum, nic->hwaddr, 6) == 0) {
memcpy(ptr->nodenum, nic->hwaddr, 6);
first = 0;
}
nic = nic->next;
}
ptr->socket = ntohs(ipxaddr->sa_socket);
if(ptr->socket == 0) {
ptr->socket = 1024;
ipx_socket *sptr = sockets;
while(sptr) {
if(sptr != ptr && sptr->socket == ptr->socket) {
ptr->socket++;
sptr = sockets;
continue;
}
sptr = sptr->next;
}
}
ptr->flags |= IPX_BOUND;
debug("...bound to net=%hhx:%hhx:%hhx:%hhx node=%hhx:%hhx:%hhx:%hhx:%hhx:%hhx socket=%hu)",
ptr->netnum[0],
ptr->netnum[1],
ptr->netnum[2],
ptr->netnum[3],
ptr->nodenum[0],
ptr->nodenum[1],
ptr->nodenum[2],
ptr->nodenum[3],
ptr->nodenum[4],
ptr->nodenum[5],
ptr->socket
);
}else{
debug("...failed");
}
RETURN(rval);
}else{
RETURN(r_bind(fd, addr, addrlen));
}
}
int WSAAPI getsockname(SOCKET fd, struct sockaddr *addr, int *addrlen) {
struct sockaddr_ipx *ipxaddr = (struct sockaddr_ipx*)addr;
ipx_socket *ptr = get_socket(fd);
if(ptr) {
if(ptr->flags & IPX_BOUND) {
if(*addrlen < sizeof(struct sockaddr_ipx)) {
*addrlen = sizeof(struct sockaddr_ipx);
RETURN_WSA(WSAEFAULT, -1);
}
ipxaddr->sa_family = AF_IPX;
memcpy(ipxaddr->sa_netnum, ptr->netnum, 4);
memcpy(ipxaddr->sa_nodenum, ptr->nodenum, 6);
ipxaddr->sa_socket = htons(ptr->socket);
*addrlen = sizeof(struct sockaddr_ipx);
RETURN(0);
}else{
RETURN_WSA(WSAEINVAL, -1);
}
}else{
RETURN(r_getsockname(fd, addr, addrlen));
}
}
int WSAAPI recvfrom(SOCKET fd, char *buf, int len, int flags, struct sockaddr *addr, int *addrlen) {
struct sockaddr_ipx *from = (struct sockaddr_ipx*)addr;
ipx_socket *ptr = get_socket(fd);
if(ptr) {
if(!(ptr->flags & IPX_BOUND)) {
RETURN_WSA(WSAEINVAL, -1);
}
struct ipx_packet *packet = malloc(PACKET_BUF_SIZE);
if(!packet) {
RETURN_WSA(ERROR_OUTOFMEMORY, -1);
}
int rval = r_recv(fd, (char*)packet, PACKET_BUF_SIZE, flags);
if(rval == -1) {
free(packet);
RETURN(-1);
}
if(from) {
from->sa_family = AF_IPX;
memcpy(from->sa_netnum, packet->src_net, 4);
memcpy(from->sa_nodenum, packet->src_node, 6);
from->sa_socket = htons(packet->src_socket);
if(addrlen) {
*addrlen = sizeof(struct sockaddr_ipx);
}
}
if(packet->size <= len) {
memcpy(buf, packet->data, packet->size);
rval = packet->size;
free(packet);
RETURN(rval);
}else{
memcpy(buf, packet->data, len);
free(packet);
RETURN_WSA(WSAEMSGSIZE, -1);
}
}else{
RETURN(r_recvfrom(fd, buf, len, flags, addr, addrlen));
}
}
int WSAAPI recv(SOCKET fd, char *buf, int len, int flags) {
ipx_socket *ptr = get_socket(fd);
if(ptr) {
if(!(ptr->flags & IPX_BOUND)) {
RETURN_WSA(WSAEINVAL, -1);
}
struct ipx_packet *packet = malloc(PACKET_BUF_SIZE);
if(!packet) {
RETURN_WSA(ERROR_OUTOFMEMORY, -1);
}
int rval = r_recv(fd, (char*)packet, PACKET_BUF_SIZE, flags);
if(rval == -1) {
free(packet);
RETURN(-1);
}
if(packet->size <= len) {
memcpy(buf, packet->data, packet->size);
rval = packet->size;
free(packet);
RETURN(rval);
}else{
memcpy(buf, packet->data, len);
free(packet);
RETURN_WSA(WSAEMSGSIZE, -1);
}
}else{
RETURN(r_recv(fd, buf, len, flags));
}
}
#define CHECK_OPTLEN(size) \
if(*optlen < size) {\
*optlen = size;\
RETURN_WSA(WSAEFAULT, -1);\
}\
*optlen = size;
int WSAAPI getsockopt(SOCKET fd, int level, int optname, char FAR *optval, int FAR *optlen) {
int* intval = (int*)optval;
ipx_socket *ptr = get_socket(fd);
if(ptr) {
if(level == NSPROTO_IPX) {
if(optname == IPX_PTYPE) {
CHECK_OPTLEN(sizeof(int));
*intval = ptr->s_ptype;
}
if(optname == IPX_FILTERPTYPE) {
CHECK_OPTLEN(sizeof(int));
*intval = ptr->f_ptype;
}
if(optname == IPX_MAXSIZE) {
CHECK_OPTLEN(sizeof(int));
*intval = MAX_PACKET_SIZE;
}
if(optname == IPX_ADDRESS) {
CHECK_OPTLEN(sizeof(IPX_ADDRESS_DATA));
IPX_ADDRESS_DATA *ipxdata = (IPX_ADDRESS_DATA*)optval;
ipx_nic *nic = nics;
int i = 0;
while(nic && i < ipxdata->adapternum) {
nic = nic->next;
i++;
}
if(!nic) {
WSASetLastError(ERROR_NO_DATA);
return -1;
}
memset(ipxdata->netnum, 0, 4);
memcpy(ipxdata->nodenum, nic->hwaddr, 6);
/* TODO: LAN/WAN detection, link speed detection */
ipxdata->wan = FALSE;
ipxdata->status = FALSE;
ipxdata->maxpkt = MAX_PACKET_SIZE;
ipxdata->linkspeed = 100000; /* 10MBps */
}
if(optname == IPX_MAX_ADAPTER_NUM) {
CHECK_OPTLEN(sizeof(int));
*intval = 0;
ipx_nic *nic = nics;
while(nic) {
(*intval)++;
nic = nic->next;
}
}
RETURN(0);
}
}
RETURN(r_getsockopt(fd, level, optname, optval, optlen));
}
int WSAAPI setsockopt(SOCKET fd, int level, int optname, const char FAR *optval, int optlen) {
int *intval = (int*)optval;
BOOL *bval = (BOOL*)optval;
ipx_socket *sockptr = get_socket(fd);
if(sockptr) {
if(level == NSPROTO_IPX) {
if(optname == IPX_PTYPE) {
sockptr->s_ptype = *intval;
}
if(optname == IPX_FILTERPTYPE) {
sockptr->f_ptype = *intval;
sockptr->flags |= IPX_FILTER;
}
if(optname == IPX_STOPFILTERPTYPE) {
sockptr->flags &= ~IPX_FILTER;
}
RETURN(0);
}
if(level == SOL_SOCKET) {
if(optname == SO_BROADCAST) {
if(*bval == TRUE) {
sockptr->flags |= IPX_BROADCAST;
}else{
sockptr->flags &= ~IPX_BROADCAST;
}
}
}
}
RETURN(r_setsockopt(fd, level, optname, optval, optlen));
}
int WSAAPI sendto(SOCKET fd, const char *buf, int len, int flags, const struct sockaddr *addr, int addrlen) {
struct sockaddr_ipx *ipxaddr = (struct sockaddr_ipx*)addr;
unsigned char z6[] = {0,0,0,0,0,0};
int sval, psize;
struct sockaddr_in saddr;
ipx_packet *packet;
ipx_nic *nic;
ipx_socket *sockptr = get_socket(fd);
if(sockptr) {
if(!addr || addrlen < sizeof(struct sockaddr_ipx)) {
RETURN_WSA(WSAEDESTADDRREQ, -1);
}
if(!(sockptr->flags & IPX_SEND)) {
RETURN_WSA(WSAESHUTDOWN, -1);
}
if(!(sockptr->flags & IPX_BOUND)) {
debug("fd %d: NO IMPLICIT BIND! SHIT!");
/* TODO: Implicit bind */
}
if(len > MAX_PACKET_SIZE) {
RETURN_WSA(WSAEMSGSIZE, -1);
}
psize = sizeof(ipx_packet)+len-1;
packet = malloc(psize);
if(!packet) {
RETURN_WSA(ERROR_OUTOFMEMORY, -1);
}
INIT_PACKET(packet);
packet->ptype = sockptr->s_ptype;
memcpy(packet->dest_net, ipxaddr->sa_netnum, 4);
memcpy(packet->dest_node, ipxaddr->sa_nodenum, 6);
packet->dest_socket = ipxaddr->sa_socket;
packet->size = htons(len);
memcpy(packet->data, buf, len);
lock_mutex();
ipx_host *hptr = find_host(packet->dest_node);
for(nic = nics; nic; nic = nic->next) {
if((
memcmp(sockptr->nodenum, nic->hwaddr, 6) == 0 ||
memcmp(sockptr->nodenum, z6, 6) == 0)
) {
memset(packet->src_net, 0, 4);
memcpy(packet->src_node, nic->hwaddr, 6);
packet->src_socket = htons(sockptr->socket);
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = htonl(hptr ? hptr->ipaddr : nic->bcast);
saddr.sin_port = htons(PORT);
sval = r_sendto(net_fd, (char*)packet, psize, 0, (struct sockaddr*)&saddr, sizeof(saddr));
if(sval == -1) {
len = -1;
break;
}
}
}
free(packet);
RETURN(len);
}else{
RETURN(r_sendto(fd, buf, len, flags, addr, addrlen));
}
}
int PASCAL shutdown(SOCKET fd, int cmd) {
ipx_socket *sockptr = get_socket(fd);
if(sockptr) {
if(cmd == SD_SEND || cmd == SD_BOTH) {
sockptr->flags &= ~IPX_SEND;
}
if(cmd == SD_RECEIVE || cmd == SD_BOTH) {
sockptr->flags &= ~IPX_RECV;
}
RETURN(0);
}else{
RETURN(r_shutdown(fd, cmd));
}
}

66
src/winstuff.h Normal file
View File

@ -0,0 +1,66 @@
/* ipxwrapper - Winsock/win32 stuff
* Copyright (C) 2008 Daniel Collins <solemnwarning@solemnwarning.net>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*
* 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 the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef WINSTUFF_H
#define WINSTUFF_H
#define IPX_PTYPE 0x4000
#define IPX_FILTERPTYPE 0x4001
#define IPX_STOPFILTERPTYPE 0x4003
#define IPX_MAXSIZE 0x4006
#define IPX_ADDRESS 0x4007
#define IPX_MAX_ADAPTER_NUM 0x400D
typedef struct _PROTOCOL_INFOA {
DWORD dwServiceFlags ;
INT iAddressFamily ;
INT iMaxSockAddr ;
INT iMinSockAddr ;
INT iSocketType ;
INT iProtocol ;
DWORD dwMessageSize ;
LPSTR lpProtocol ;
} PROTOCOL_INFOA;
typedef struct _PROTOCOL_INFOW {
DWORD dwServiceFlags ;
INT iAddressFamily ;
INT iMaxSockAddr ;
INT iMinSockAddr ;
INT iSocketType ;
INT iProtocol ;
DWORD dwMessageSize ;
LPWSTR lpProtocol ;
} PROTOCOL_INFOW;
typedef struct _IPX_ADDRESS_DATA {
INT adapternum;
UCHAR netnum[4];
UCHAR nodenum[6];
BOOLEAN wan;
BOOLEAN status;
INT maxpkt;
ULONG linkspeed;
} IPX_ADDRESS_DATA;
#ifdef UNICODE
typedef PROTOCOL_INFOW PROTOCOL_INFO;
#else
typedef PROTOCOL_INFOA PROTOCOL_INFO;
#endif
#endif /* !WINSTUFF_H */

66
src/wsock32.def Normal file
View File

@ -0,0 +1,66 @@
LIBRARY WSOCK32.dll
EXPORTS
accept @1
bind @2
closesocket @3
connect @4
getpeername @5
getsockname @6
getsockopt @7
htonl @8
htons @9
inet_addr @10
inet_ntoa @11
ioctlsocket @12
listen @13
ntohl @14
ntohs @15
recv @16
recvfrom @17
select @18
send @19
sendto @20
setsockopt @21
shutdown @22
socket @23
gethostbyaddr @51
gethostbyname @52
getprotobyname @53
getprotobynumber @54
getservbyname @55
getservbyport @56
gethostname @57
WSAAsyncSelect @101
WSAAsyncGetHostByAddr @102
WSAAsyncGetHostByName @103
WSAAsyncGetProtoByNumber @104
WSAAsyncGetProtoByName @105
WSAAsyncGetServByPort @106
WSAAsyncGetServByName @107
WSACancelAsyncRequest @108
WSASetBlockingHook @109
WSAUnhookBlockingHook @110
WSAGetLastError @111
WSASetLastError @112
WSACancelBlockingCall @113
WSAIsBlocking @114
WSAStartup @115
WSACleanup @116
__WSAFDIsSet @151
sethostname @1105
WSARecvEx @1107
GetAddressByNameA @1109
GetAddressByNameW @1110
EnumProtocolsA @1111
EnumProtocolsW @1112
GetTypeByNameA @1113
GetTypeByNameW @1114
GetNameByTypeA @1115
GetNameByTypeW @1116
SetServiceA @1117
SetServiceW @1118
GetServiceA @1119
GetServiceW @1120
TransmitFile @1140
AcceptEx @1141
GetAcceptExSockaddrs @1142

119
src/wsock32_stubs.txt Normal file
View File

@ -0,0 +1,119 @@
/* Stub functions will be generated for all functions declared here */
/* Declarations from MinGW headers */
int PASCAL __WSAFDIsSet(SOCKET,fd_set*);
SOCKET PASCAL accept(SOCKET,struct sockaddr*,int*);
int PASCAL connect(SOCKET,const struct sockaddr*,int);
int PASCAL ioctlsocket(SOCKET,long,u_long *);
int PASCAL getpeername(SOCKET,struct sockaddr*,int*);
unsigned long PASCAL inet_addr(const char*);
DECLARE_STDCALL_P(char *) inet_ntoa(struct in_addr);
int PASCAL listen(SOCKET,int);
int PASCAL send(SOCKET,const char*,int,int);
DECLARE_STDCALL_P(struct hostent *) gethostbyaddr(const char*,int,int);
DECLARE_STDCALL_P(struct hostent *) gethostbyname(const char*);
DECLARE_STDCALL_P(struct servent *) getservbyport(int,const char*);
DECLARE_STDCALL_P(struct servent *) getservbyname(const char*,const char*);
DECLARE_STDCALL_P(struct protoent *) getprotobynumber(int);
DECLARE_STDCALL_P(struct protoent *) getprotobyname(const char*);
int PASCAL WSAStartup(WORD,LPWSADATA);
int PASCAL WSACleanup(void);
void PASCAL WSASetLastError(int);
int PASCAL WSAGetLastError(void);
BOOL PASCAL WSAIsBlocking(void);
int PASCAL WSAUnhookBlockingHook(void);
FARPROC PASCAL WSASetBlockingHook(FARPROC);
int PASCAL WSACancelBlockingCall(void);
HANDLE PASCAL WSAAsyncGetServByName(HWND,u_int,const char*,const char*,char*,int);
HANDLE PASCAL WSAAsyncGetServByPort(HWND,u_int,int,const char*,char*,int);
HANDLE PASCAL WSAAsyncGetProtoByName(HWND,u_int,const char*,char*,int);
HANDLE PASCAL WSAAsyncGetProtoByNumber(HWND,u_int,int,char*,int);
HANDLE PASCAL WSAAsyncGetHostByName(HWND,u_int,const char*,char*,int);
HANDLE PASCAL WSAAsyncGetHostByAddr(HWND,u_int,const char*,int,int,char*,int);
int PASCAL WSACancelAsyncRequest(HANDLE);
int PASCAL WSAAsyncSelect(SOCKET,HWND,u_int,long);
u_long PASCAL htonl(u_long);
u_long PASCAL ntohl(u_long);
u_short PASCAL htons(u_short);
u_short PASCAL ntohs(u_short);
int PASCAL select(int,fd_set*,fd_set*,fd_set*,const struct timeval*);
int PASCAL gethostname(char*,int);
SOCKET WINAPI WSAAccept(SOCKET, struct sockaddr *, LPINT, LPCONDITIONPROC, DWORD);
INT WINAPI WSAAddressToStringA(LPSOCKADDR, DWORD, LPWSAPROTOCOL_INFOA, LPSTR, LPDWORD);
INT WINAPI WSAAddressToStringW(LPSOCKADDR, DWORD, LPWSAPROTOCOL_INFOW, LPWSTR, LPDWORD);
BOOL WINAPI WSACloseEvent(WSAEVENT);
int WINAPI WSAConnect(SOCKET, const struct sockaddr *, int, LPWSABUF, LPWSABUF, LPQOS, LPQOS);
WSAEVENT WINAPI WSACreateEvent(void);
int WINAPI WSADuplicateSocketA(SOCKET, DWORD, LPWSAPROTOCOL_INFOA);
int WINAPI WSADuplicateSocketW(SOCKET, DWORD, LPWSAPROTOCOL_INFOW);
INT WINAPI WSAEnumNameSpaceProvidersA(LPDWORD, LPWSANAMESPACE_INFOA);
INT WINAPI WSAEnumNameSpaceProvidersW(LPDWORD, LPWSANAMESPACE_INFOW);
int WINAPI WSAEnumNetworkEvents(SOCKET, WSAEVENT, LPWSANETWORKEVENTS);
int WINAPI WSAEnumProtocolsA(LPINT, LPWSAPROTOCOL_INFOA, LPDWORD);
int WINAPI WSAEnumProtocolsW(LPINT, LPWSAPROTOCOL_INFOW, LPDWORD);
int WINAPI WSAEventSelect(SOCKET, WSAEVENT, long);
BOOL WINAPI WSAGetOverlappedResult(SOCKET, LPWSAOVERLAPPED, LPDWORD, BOOL, LPDWORD);
BOOL WINAPI WSAGetQOSByName(SOCKET, LPWSABUF, LPQOS);
INT WINAPI WSAGetServiceClassInfoA(LPGUID, LPGUID, LPDWORD, LPWSASERVICECLASSINFOA);
INT WINAPI WSAGetServiceClassInfoW(LPGUID, LPGUID, LPDWORD, LPWSASERVICECLASSINFOW);
INT WINAPI WSAGetServiceClassNameByClassIdA(LPGUID, LPSTR, LPDWORD);
INT WINAPI WSAGetServiceClassNameByClassIdW(LPGUID, LPWSTR, LPDWORD);
int WINAPI WSAHtonl(SOCKET, unsigned long, unsigned long *);
int WINAPI WSAHtons(SOCKET, unsigned short, unsigned short *);
INT WINAPI WSAInstallServiceClassA(LPWSASERVICECLASSINFOA);
INT WINAPI WSAInstallServiceClassW(LPWSASERVICECLASSINFOW);
int WINAPI WSAIoctl(SOCKET, DWORD, LPVOID, DWORD, LPVOID, DWORD, LPDWORD, LPWSAOVERLAPPED, LPWSAOVERLAPPED_COMPLETION_ROUTINE);
SOCKET WINAPI WSAJoinLeaf(SOCKET, const struct sockaddr *, int, LPWSABUF, LPWSABUF, LPQOS, LPQOS, DWORD);
INT WINAPI WSALookupServiceBeginA(LPWSAQUERYSETA, DWORD, LPHANDLE);
INT WINAPI WSALookupServiceBeginW(LPWSAQUERYSETW, DWORD, LPHANDLE);
INT WINAPI WSALookupServiceNextA(HANDLE, DWORD, LPDWORD, LPWSAQUERYSETA);
INT WINAPI WSALookupServiceNextW(HANDLE, DWORD, LPDWORD, LPWSAQUERYSETW);
INT WINAPI WSALookupServiceEnd(HANDLE);
int WINAPI WSANSPIoctl(HANDLE,DWORD,LPVOID,DWORD,LPVOID,DWORD,LPDWORD,LPWSACOMPLETION); /* XP or .NET Server */
int WINAPI WSANtohl(SOCKET, unsigned long, unsigned long *);
int WINAPI WSANtohs(SOCKET, unsigned short, unsigned short *);
int WINAPI WSARecv(SOCKET, LPWSABUF, DWORD, LPDWORD, LPDWORD, LPWSAOVERLAPPED, LPWSAOVERLAPPED_COMPLETION_ROUTINE);
int WINAPI WSARecvDisconnect(SOCKET, LPWSABUF);
int WINAPI WSARecvFrom(SOCKET, LPWSABUF, DWORD, LPDWORD, LPDWORD, struct sockaddr *, LPINT, LPWSAOVERLAPPED, LPWSAOVERLAPPED_COMPLETION_ROUTINE);
INT WINAPI WSARemoveServiceClass(LPGUID);
BOOL WINAPI WSAResetEvent(WSAEVENT);
int WINAPI WSASend(SOCKET, LPWSABUF, DWORD, LPDWORD, DWORD, LPWSAOVERLAPPED, LPWSAOVERLAPPED_COMPLETION_ROUTINE);
int WINAPI WSASendDisconnect(SOCKET, LPWSABUF);
int WINAPI WSASendTo(SOCKET, LPWSABUF, DWORD, LPDWORD, DWORD, const struct sockaddr *, int, LPWSAOVERLAPPED, LPWSAOVERLAPPED_COMPLETION_ROUTINE);
BOOL WINAPI WSASetEvent(WSAEVENT);
INT WSAAPI WSASetServiceA(LPWSAQUERYSETA, WSAESETSERVICEOP, DWORD);
INT WINAPI WSASetServiceW(LPWSAQUERYSETW, WSAESETSERVICEOP, DWORD);
SOCKET WINAPI WSASocketA(int, int, int, LPWSAPROTOCOL_INFOA, GROUP, DWORD);
SOCKET WINAPI WSASocketW(int, int, int, LPWSAPROTOCOL_INFOW, GROUP, DWORD);
INT WINAPI WSAStringToAddressA(LPSTR, INT, LPWSAPROTOCOL_INFOA, LPSOCKADDR, LPINT);
INT WINAPI WSAStringToAddressW(LPWSTR, INT, LPWSAPROTOCOL_INFOW, LPSOCKADDR, LPINT);
DWORD WINAPI WSAWaitForMultipleEvents(DWORD, const WSAEVENT *, BOOL, DWORD, BOOL);
BOOL PASCAL AcceptEx(SOCKET,SOCKET,PVOID,DWORD,DWORD,DWORD,LPDWORD,LPOVERLAPPED);
VOID PASCAL GetAcceptExSockaddrs(PVOID,DWORD,DWORD,DWORD,struct sockaddr**, LPINT, struct sockaddr**, LPINT);
INT WINAPI GetAddressByNameA(DWORD,LPGUID,LPSTR,LPINT,DWORD,LPSERVICE_ASYNC_INFO,LPVOID,LPDWORD,LPSTR,LPDWORD);
INT WINAPI GetAddressByNameW(DWORD,LPGUID,LPWSTR,LPINT,DWORD,LPSERVICE_ASYNC_INFO,LPVOID,LPDWORD,LPWSTR,LPDWORD);
INT WINAPI SetServiceA(DWORD,DWORD,DWORD,LPSERVICE_INFOA,LPSERVICE_ASYNC_INFO,LPDWORD);
INT WINAPI SetServiceW(DWORD,DWORD,DWORD,LPSERVICE_INFOW,LPSERVICE_ASYNC_INFO,LPDWORD);
BOOL PASCAL TransmitFile(SOCKET,HANDLE,DWORD,DWORD,LPOVERLAPPED,LPTRANSMIT_FILE_BUFFERS,DWORD);
/* Declarations from the win32 SDK and MSDN */
INT APIENTRY GetNameByTypeA(IN LPGUID,IN OUT LPSTR,IN DWORD);
INT APIENTRY GetNameByTypeW(IN LPGUID,IN OUT LPWSTR,IN DWORD);
INT APIENTRY GetServiceA(DWORD, LPGUID, LPSTR,DWORD,LPVOID,LPDWORD,LPSERVICE_ASYNC_INFO);
INT APIENTRY GetServiceW(DWORD, LPGUID, LPWSTR,DWORD,LPVOID,LPDWORD,LPSERVICE_ASYNC_INFO);
INT APIENTRY GetTypeByNameA(LPSTR,LPGUID);
INT APIENTRY GetTypeByNameW(LPWSTR,LPGUID);
int APIENTRY sethostname(char*,int);
INT APIENTRY EnumProtocolsA(LPINT,LPVOID,LPDWORD);
INT APIENTRY EnumProtocolsW(LPINT,LPVOID,LPDWORD);
int PASCAL FAR WSARecvEx(SOCKET,char*,int,int*);
int WSAAPI bind(SOCKET,const struct sockaddr*,int);
int WSAAPI closesocket(SOCKET);
int WSAAPI getsockname(SOCKET,struct sockaddr*,int*);
int WSAAPI getsockopt(SOCKET,int,int,char*,int*);
int WSAAPI recv(SOCKET,char*,int,int);
int WSAAPI recvfrom(SOCKET,char*,int,int,struct sockaddr*,int*);
int WSAAPI sendto(SOCKET,const char*,int,int,const struct sockaddr*,int);
int WSAAPI setsockopt(SOCKET,int,int,const char*,int);
int WSAAPI shutdown(SOCKET,int);
SOCKET WSAAPI socket(int,int,int);