mirror of
https://github.com/solemnwarning/ipxwrapper
synced 2024-12-30 16:45:37 +01:00
Started rewrite of router code to be isolated from the rest of IPXWrapper.
This commit is contained in:
parent
bca5c8f978
commit
9f62a21b30
4
Makefile
4
Makefile
@ -53,7 +53,7 @@ ipxconfig.exe: src/ipxconfig.cpp
|
|||||||
$(CXX) $(CXXFLAGS) -static-libgcc -static-libstdc++ -Wl,-s -D_WIN32_IE=0x0400 -mwindows -o ipxconfig.exe src/ipxconfig.cpp -liphlpapi
|
$(CXX) $(CXXFLAGS) -static-libgcc -static-libstdc++ -Wl,-s -D_WIN32_IE=0x0400 -mwindows -o ipxconfig.exe src/ipxconfig.cpp -liphlpapi
|
||||||
|
|
||||||
dpwsockx.dll: src/directplay.o src/log.o src/dpwsockx_stubs.o src/common.o ipxwrapper.dll
|
dpwsockx.dll: src/directplay.o src/log.o src/dpwsockx_stubs.o src/common.o ipxwrapper.dll
|
||||||
$(CC) $(CFLAGS) -Wl,--enable-stdcall-fixup,-s -shared -o dpwsockx.dll src/directplay.o src/log.o src/common.o src/dpwsockx_stubs.o src/dpwsockx.def -L. -lipxwrapper -lwsock32
|
$(CC) $(CFLAGS) -Wl,--enable-stdcall-fixup,-s -shared -o dpwsockx.dll src/directplay.o src/log.o src/common.o src/dpwsockx_stubs.o src/dpwsockx.def -L. -lipxwrapper -lwsock32 -liphlpapi
|
||||||
|
|
||||||
src/ipxwrapper_stubs.s: src/ipxwrapper_stubs.txt
|
src/ipxwrapper_stubs.s: src/ipxwrapper_stubs.txt
|
||||||
perl mkstubs.pl src/ipxwrapper_stubs.txt src/ipxwrapper_stubs.s
|
perl mkstubs.pl src/ipxwrapper_stubs.txt src/ipxwrapper_stubs.s
|
||||||
@ -68,7 +68,7 @@ src/dpwsockx_stubs.s: src/dpwsockx_stubs.txt
|
|||||||
perl mkstubs.pl src/dpwsockx_stubs.txt src/dpwsockx_stubs.s dpwsockx.dll
|
perl mkstubs.pl src/dpwsockx_stubs.txt src/dpwsockx_stubs.s dpwsockx.dll
|
||||||
|
|
||||||
%.dll: src/stubdll.o src/%_stubs.o src/log.o src/common.o src/%.def
|
%.dll: src/stubdll.o src/%_stubs.o src/log.o src/common.o src/%.def
|
||||||
$(CC) $(CFLAGS) -Wl,--enable-stdcall-fixup,-s -shared -o $@ $^
|
$(CC) $(CFLAGS) -Wl,--enable-stdcall-fixup,-s -shared -o $@ $^ -liphlpapi
|
||||||
|
|
||||||
src/%_stubs.o: src/%_stubs.s
|
src/%_stubs.o: src/%_stubs.s
|
||||||
nasm -f win32 -o $@ $<
|
nasm -f win32 -o $@ $<
|
||||||
|
116
src/common.c
116
src/common.c
@ -16,8 +16,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <iphlpapi.h>
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
HKEY regkey = NULL;
|
HKEY regkey = NULL;
|
||||||
|
|
||||||
@ -104,3 +106,117 @@ HMODULE load_sysdll(const char *name) {
|
|||||||
|
|
||||||
return dll;
|
return dll;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get virtual IPX interfaces
|
||||||
|
* Select a single interface by setting ifnum >= 0
|
||||||
|
*/
|
||||||
|
struct ipx_interface *get_interfaces(int ifnum) {
|
||||||
|
IP_ADAPTER_INFO *ifroot, tbuf;
|
||||||
|
ULONG bufsize = sizeof(IP_ADAPTER_INFO);
|
||||||
|
|
||||||
|
int err = GetAdaptersInfo(&tbuf, &bufsize);
|
||||||
|
if(err == ERROR_NO_DATA) {
|
||||||
|
log_printf("No network interfaces detected!");
|
||||||
|
return NULL;
|
||||||
|
}else if(err != ERROR_SUCCESS && err != ERROR_BUFFER_OVERFLOW) {
|
||||||
|
log_printf("Error fetching network interfaces: %s", w32_error(err));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!(ifroot = malloc(bufsize))) {
|
||||||
|
log_printf("Out of memory! (Tried to allocate %u bytes)", (unsigned int)bufsize);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = GetAdaptersInfo(ifroot, &bufsize);
|
||||||
|
if(err != ERROR_SUCCESS) {
|
||||||
|
log_printf("Error fetching network interfaces: %s", w32_error(err));
|
||||||
|
|
||||||
|
free(ifroot);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ipx_interface *nics = NULL, *enic = NULL;
|
||||||
|
|
||||||
|
IP_ADAPTER_INFO *ifptr = ifroot;
|
||||||
|
int this_ifnum = 0;
|
||||||
|
|
||||||
|
while(ifptr) {
|
||||||
|
if(ifnum >= 0 && this_ifnum++ != ifnum) {
|
||||||
|
ifptr = ifptr->Next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct reg_value rv;
|
||||||
|
int got_rv = 0;
|
||||||
|
|
||||||
|
char vname[18];
|
||||||
|
NODE_TO_STRING(vname, ifptr->Address);
|
||||||
|
|
||||||
|
if(reg_get_bin(vname, &rv, sizeof(rv)) == sizeof(rv)) {
|
||||||
|
got_rv = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(got_rv && !rv.enabled) {
|
||||||
|
/* Interface has been disabled, don't add it */
|
||||||
|
ifptr = ifptr->Next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ipx_interface *nnic = malloc(sizeof(struct ipx_interface));
|
||||||
|
if(!nnic) {
|
||||||
|
log_printf("Out of memory! (Tried to allocate %u bytes)", (unsigned int)sizeof(struct ipx_interface));
|
||||||
|
|
||||||
|
free_interfaces(nics);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
nnic->ipaddr = inet_addr(ifptr->IpAddressList.IpAddress.String);
|
||||||
|
nnic->netmask = inet_addr(ifptr->IpAddressList.IpMask.String);
|
||||||
|
nnic->bcast = nnic->ipaddr | ~nnic->netmask;
|
||||||
|
|
||||||
|
memcpy(nnic->hwaddr, ifptr->Address, 6);
|
||||||
|
|
||||||
|
if(got_rv) {
|
||||||
|
memcpy(nnic->ipx_net, rv.ipx_net, 4);
|
||||||
|
memcpy(nnic->ipx_node, rv.ipx_node, 6);
|
||||||
|
}else{
|
||||||
|
unsigned char net[] = {0,0,0,1};
|
||||||
|
|
||||||
|
memcpy(nnic->ipx_net, net, 4);
|
||||||
|
memcpy(nnic->ipx_node, nnic->hwaddr, 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
nnic->next = NULL;
|
||||||
|
|
||||||
|
if(got_rv && rv.primary) {
|
||||||
|
/* Force primary flag set, insert at start of NIC list */
|
||||||
|
nnic->next = nics;
|
||||||
|
nics = nnic;
|
||||||
|
|
||||||
|
if(!enic) {
|
||||||
|
enic = nnic;
|
||||||
|
}
|
||||||
|
}else if(enic) {
|
||||||
|
enic->next = nnic;
|
||||||
|
enic = nnic;
|
||||||
|
}else{
|
||||||
|
enic = nics = nnic;
|
||||||
|
}
|
||||||
|
|
||||||
|
ifptr = ifptr->Next;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(ifroot);
|
||||||
|
|
||||||
|
return nics;
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_interfaces(struct ipx_interface *iface) {
|
||||||
|
while(iface) {
|
||||||
|
struct ipx_interface *del = iface;
|
||||||
|
iface = iface->next;
|
||||||
|
|
||||||
|
free(del);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
38
src/common.h
38
src/common.h
@ -19,6 +19,41 @@
|
|||||||
#define IPXWRAPPER_COMMON_H
|
#define IPXWRAPPER_COMMON_H
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define NET_TO_STRING(s, net) \
|
||||||
|
sprintf( \
|
||||||
|
s, "%02X:%02X:%02X:%02X", \
|
||||||
|
(unsigned int)(unsigned char)(net[0]), \
|
||||||
|
(unsigned int)(unsigned char)(net[1]), \
|
||||||
|
(unsigned int)(unsigned char)(net[2]), \
|
||||||
|
(unsigned int)(unsigned char)(net[3]) \
|
||||||
|
)
|
||||||
|
|
||||||
|
#define NODE_TO_STRING(s, node) \
|
||||||
|
sprintf( \
|
||||||
|
s, "%02X:%02X:%02X:%02X:%02X:%02X", \
|
||||||
|
(unsigned int)(unsigned char)(node[0]), \
|
||||||
|
(unsigned int)(unsigned char)(node[1]), \
|
||||||
|
(unsigned int)(unsigned char)(node[2]), \
|
||||||
|
(unsigned int)(unsigned char)(node[3]), \
|
||||||
|
(unsigned int)(unsigned char)(node[4]), \
|
||||||
|
(unsigned int)(unsigned char)(node[5]) \
|
||||||
|
)
|
||||||
|
|
||||||
|
struct ipx_interface {
|
||||||
|
uint32_t ipaddr;
|
||||||
|
uint32_t netmask;
|
||||||
|
uint32_t bcast;
|
||||||
|
|
||||||
|
unsigned char hwaddr[6];
|
||||||
|
|
||||||
|
unsigned char ipx_net[4];
|
||||||
|
unsigned char ipx_node[6];
|
||||||
|
|
||||||
|
struct ipx_interface *next;
|
||||||
|
};
|
||||||
|
|
||||||
extern HKEY regkey;
|
extern HKEY regkey;
|
||||||
|
|
||||||
@ -34,4 +69,7 @@ DWORD reg_get_bin(const char *val_name, void *buf, DWORD size);
|
|||||||
|
|
||||||
HMODULE load_sysdll(const char *name);
|
HMODULE load_sysdll(const char *name);
|
||||||
|
|
||||||
|
struct ipx_interface *get_interfaces(int ifnum);
|
||||||
|
void free_interfaces(struct ipx_interface *iface);
|
||||||
|
|
||||||
#endif /* !IPXWRAPPER_COMMON_H */
|
#endif /* !IPXWRAPPER_COMMON_H */
|
||||||
|
@ -53,26 +53,6 @@
|
|||||||
SetLastError(errnum);\
|
SetLastError(errnum);\
|
||||||
return __VA_ARGS__;
|
return __VA_ARGS__;
|
||||||
|
|
||||||
#define NET_TO_STRING(s, net) \
|
|
||||||
sprintf( \
|
|
||||||
s, "%02X:%02X:%02X:%02X", \
|
|
||||||
(unsigned int)(unsigned char)(net[0]), \
|
|
||||||
(unsigned int)(unsigned char)(net[1]), \
|
|
||||||
(unsigned int)(unsigned char)(net[2]), \
|
|
||||||
(unsigned int)(unsigned char)(net[3]) \
|
|
||||||
)
|
|
||||||
|
|
||||||
#define NODE_TO_STRING(s, node) \
|
|
||||||
sprintf( \
|
|
||||||
s, "%02X:%02X:%02X:%02X:%02X:%02X", \
|
|
||||||
(unsigned int)(unsigned char)(node[0]), \
|
|
||||||
(unsigned int)(unsigned char)(node[1]), \
|
|
||||||
(unsigned int)(unsigned char)(node[2]), \
|
|
||||||
(unsigned int)(unsigned char)(node[3]), \
|
|
||||||
(unsigned int)(unsigned char)(node[4]), \
|
|
||||||
(unsigned int)(unsigned char)(node[5]) \
|
|
||||||
)
|
|
||||||
|
|
||||||
typedef struct ipx_socket ipx_socket;
|
typedef struct ipx_socket ipx_socket;
|
||||||
typedef struct ipx_packet ipx_packet;
|
typedef struct ipx_packet ipx_packet;
|
||||||
typedef struct ipx_nic ipx_nic;
|
typedef struct ipx_nic ipx_nic;
|
||||||
|
@ -30,3 +30,4 @@ rexec
|
|||||||
rresvport
|
rresvport
|
||||||
s_perror
|
s_perror
|
||||||
sethostname
|
sethostname
|
||||||
|
inet_addr
|
||||||
|
218
src/router.c
Normal file
218
src/router.c
Normal file
@ -0,0 +1,218 @@
|
|||||||
|
/* IPXWrapper - Router code
|
||||||
|
* Copyright (C) 2011 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 "router.h"
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
/* Allocate router_vars structure and initialise all members
|
||||||
|
* Returns NULL on failure
|
||||||
|
*/
|
||||||
|
struct router_vars *router_init(BOOL global) {
|
||||||
|
struct router_vars *router = malloc(sizeof(struct router_vars));
|
||||||
|
if(!router) {
|
||||||
|
log_printf("Not enough memory to create router_vars!");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
router->running = TRUE;
|
||||||
|
router->udp_sock = -1;
|
||||||
|
router->listner = -1;
|
||||||
|
router->wsa_event = WSA_INVALID_EVENT;
|
||||||
|
router->crit_sec_init = FALSE;
|
||||||
|
router->addrs = NULL;
|
||||||
|
|
||||||
|
if(InitializeCriticalSectionAndSpinCount(&(router->crit_sec), 0x80000000)) {
|
||||||
|
router->crit_sec_init = TRUE;
|
||||||
|
}else{
|
||||||
|
log_printf("Error creating critical section: %s", w32_error(GetLastError()));
|
||||||
|
|
||||||
|
router_destroy(router);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((router->wsa_event = WSACreateEvent()) == WSA_INVALID_EVENT) {
|
||||||
|
log_printf("Error creating WSA event object: %s", w32_error(WSAGetLastError()));
|
||||||
|
|
||||||
|
router_destroy(router);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((router->udp_sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
|
||||||
|
log_printf("Error creating UDP socket: %s", w32_error(WSAGetLastError()));
|
||||||
|
|
||||||
|
router_destroy(router);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
|
||||||
|
addr.sin_family = AF_INET;
|
||||||
|
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
|
||||||
|
addr.sin_port = 9999;
|
||||||
|
|
||||||
|
if(bind(router->udp_sock, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
|
||||||
|
router_destroy(router);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(global) {
|
||||||
|
/* TODO: Global (service) router support */
|
||||||
|
}
|
||||||
|
|
||||||
|
return router;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release all resources allocated by a router and free it */
|
||||||
|
void router_destroy(struct router_vars *router) {
|
||||||
|
if(router->udp_sock != -1) {
|
||||||
|
closesocket(router->udp_sock);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(router->wsa_event != WSA_INVALID_EVENT) {
|
||||||
|
WSACloseEvent(router->wsa_event);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(router->crit_sec_init) {
|
||||||
|
DeleteCriticalSection(&(router->crit_sec));
|
||||||
|
}
|
||||||
|
|
||||||
|
free(router);
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD router_main(void *arg) {
|
||||||
|
struct router_vars *router = arg;
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
WaitForSingleObject(router->wsa_event, INFINITE);
|
||||||
|
|
||||||
|
EnterCriticalSection(&(router->crit_sec));
|
||||||
|
|
||||||
|
if(!router->running) {
|
||||||
|
LeaveCriticalSection(&(router->crit_sec));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: Step through sockets, deal with timeouts/etc */
|
||||||
|
|
||||||
|
LeaveCriticalSection(&(router->crit_sec));
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int router_bind(struct router_vars *router, SOCKET control, SOCKET sock, struct sockaddr_ipx *addr) {
|
||||||
|
struct ipx_interface *ifaces = get_interfaces(-1), *iface;
|
||||||
|
unsigned char z6[] = {0,0,0,0,0,0};
|
||||||
|
|
||||||
|
for(iface = ifaces; iface; iface = iface->next) {
|
||||||
|
if(
|
||||||
|
(memcmp(addr->sa_netnum, iface->ipx_net, 4) == 0 || memcmp(addr->sa_netnum, z6, 4) == 0) &&
|
||||||
|
(memcmp(addr->sa_nodenum, iface->ipx_node, 6) == 0 || memcmp(addr->sa_nodenum, z6, 6) == 0)
|
||||||
|
) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!iface) {
|
||||||
|
log_printf("bind failed: no such address");
|
||||||
|
|
||||||
|
free_interfaces(ifaces);
|
||||||
|
|
||||||
|
WSASetLastError(WSAEADDRNOTAVAIL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(addr->sa_netnum, iface->ipx_net, 4);
|
||||||
|
memcpy(addr->sa_nodenum, iface->ipx_node, 6);
|
||||||
|
|
||||||
|
free_interfaces(ifaces);
|
||||||
|
|
||||||
|
EnterCriticalSection(&(router->crit_sec));
|
||||||
|
|
||||||
|
if(addr->sa_socket == 0) {
|
||||||
|
/* Automatic socket allocations start at 1024, I have no idea if
|
||||||
|
* this is normal IPX behaviour, but IP does it and it doesn't seem
|
||||||
|
* to interfere with any IPX software I've tested.
|
||||||
|
*/
|
||||||
|
|
||||||
|
uint16_t s = 1024;
|
||||||
|
struct router_addr *a = router->addrs;
|
||||||
|
|
||||||
|
while(a) {
|
||||||
|
if(ntohs(a->addr.sa_socket) == s) {
|
||||||
|
if(s == 65535) {
|
||||||
|
log_printf("bind failed: out of sockets?!");
|
||||||
|
|
||||||
|
LeaveCriticalSection(&(router->crit_sec));
|
||||||
|
|
||||||
|
WSASetLastError(WSAEADDRNOTAVAIL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
s++;
|
||||||
|
a = router->addrs;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
a = a->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
addr->sa_socket = htons(s);
|
||||||
|
}else if(addr->sa_family != AF_IPX_SHARE) {
|
||||||
|
/* Test if any bound socket is using the requested socket number. */
|
||||||
|
|
||||||
|
struct router_addr *a = router->addrs;
|
||||||
|
|
||||||
|
while(a) {
|
||||||
|
if(a->addr.sa_socket == addr->sa_socket) {
|
||||||
|
log_printf("bind failed: requested socket in use");
|
||||||
|
|
||||||
|
LeaveCriticalSection(&(router->crit_sec));
|
||||||
|
|
||||||
|
WSASetLastError(WSAEADDRINUSE);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
a = a->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct router_addr *new_addr = malloc(sizeof(struct router_addr));
|
||||||
|
if(!new_addr) {
|
||||||
|
LeaveCriticalSection(&(router->crit_sec));
|
||||||
|
|
||||||
|
WSASetLastError(ERROR_OUTOFMEMORY);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(&(new_addr->addr), addr, sizeof(struct sockaddr_ipx));
|
||||||
|
|
||||||
|
new_addr->local_port = 0;
|
||||||
|
new_addr->ws_socket = sock;
|
||||||
|
new_addr->control_socket = control;
|
||||||
|
new_addr->next = NULL;
|
||||||
|
|
||||||
|
router->addrs = new_addr;
|
||||||
|
|
||||||
|
LeaveCriticalSection(&(router->crit_sec));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
58
src/router.h
Normal file
58
src/router.h
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
/* IPXWrapper - Router header
|
||||||
|
* Copyright (C) 2011 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_ROUTER_H
|
||||||
|
#define IPXWRAPPER_ROUTER_H
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <winsock2.h>
|
||||||
|
#include <wsipx.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/* Special address family for use when binding AF_IPX sockets, allows multiple
|
||||||
|
* sockets to share the same address.
|
||||||
|
*/
|
||||||
|
#define AF_IPX_SHARE 42
|
||||||
|
|
||||||
|
struct router_addr {
|
||||||
|
struct sockaddr_ipx addr;
|
||||||
|
|
||||||
|
uint16_t local_port; /* Local UDP port */
|
||||||
|
SOCKET ws_socket; /* Application socket */
|
||||||
|
SOCKET control_socket; /* Control socket */
|
||||||
|
|
||||||
|
struct router_addr *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct router_vars {
|
||||||
|
BOOL running;
|
||||||
|
|
||||||
|
SOCKET udp_sock;
|
||||||
|
SOCKET listner;
|
||||||
|
|
||||||
|
WSAEVENT wsa_event;
|
||||||
|
|
||||||
|
CRITICAL_SECTION crit_sec;
|
||||||
|
BOOL crit_sec_init;
|
||||||
|
|
||||||
|
struct router_addr *addrs;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct router_vars *router_init(BOOL global);
|
||||||
|
void router_destroy(struct router_vars *router);
|
||||||
|
|
||||||
|
#endif /* !IPXWRAPPER_ROUTER_H */
|
Loading…
x
Reference in New Issue
Block a user