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:
commit
4d28856065
63
Makefile
Normal file
63
Makefile
Normal 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
109
mkstubs.pl
Normal 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
428
src/ipxwrapper.c
Normal 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
15
src/ipxwrapper.def
Normal 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
159
src/ipxwrapper.h
Normal 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
27
src/ipxwrapper_stubs.txt
Normal 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
23
src/mswsock.def
Normal 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
24
src/mswsock_stubs.txt
Normal 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
93
src/stubdll.c
Normal 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
637
src/winsock.c
Normal 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
66
src/winstuff.h
Normal 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
66
src/wsock32.def
Normal 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
119
src/wsock32_stubs.txt
Normal 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);
|
Loading…
x
Reference in New Issue
Block a user