mirror of
https://github.com/solemnwarning/ipxwrapper
synced 2024-12-30 16:45:37 +01:00
REFACTOR ALL THE THINGS.
This commit is contained in:
parent
c836c55ee4
commit
ebcf1673e2
4
Makefile
4
Makefile
@ -26,7 +26,7 @@ CXXFLAGS := $(CFLAGS)
|
||||
VERSION := r$(shell svn info | grep Revision | sed -e 's/.*: //')
|
||||
|
||||
IPXWRAPPER_DEPS := src/ipxwrapper.o src/winsock.o src/ipxwrapper_stubs.o src/log.o src/common.o \
|
||||
src/interface.o src/router.o src/ipxwrapper.def src/addrcache.o
|
||||
src/interface.o src/router.o src/ipxwrapper.def src/addrcache.o src/config.o src/addr.o
|
||||
|
||||
BIN_FILES := changes.txt license.txt readme.txt ipxwrapper.dll mswsock.dll wsock32.dll ipxconfig.exe \
|
||||
ipxrouter.exe dpwsockx.dll directplay-win32.reg directplay-win64.reg
|
||||
@ -69,7 +69,7 @@ ipxconfig.exe: src/ipxconfig.cpp icons/ipxconfig.o
|
||||
dpwsockx.dll: src/directplay.o src/log.o src/dpwsockx_stubs.o src/common.o
|
||||
$(CC) $(CFLAGS) -Wl,--enable-stdcall-fixup -shared -o dpwsockx.dll src/directplay.o src/log.o src/common.o src/dpwsockx_stubs.o src/dpwsockx.def -lwsock32
|
||||
|
||||
ipxrouter.exe: src/router-exe.o src/router.o src/interface.o src/common.o src/log.o icons/ipxrouter.o
|
||||
ipxrouter.exe: src/router-exe.o src/router.o src/interface.o src/common.o src/log.o icons/ipxrouter.o src/config.o src/addr.o
|
||||
$(CC) $(CFLAGS) -static-libgcc -mwindows -o ipxrouter.exe $^ -lws2_32 -liphlpapi
|
||||
|
||||
src/ipxwrapper_stubs.s: src/ipxwrapper_stubs.txt
|
||||
|
133
src/addr.c
Normal file
133
src/addr.c
Normal file
@ -0,0 +1,133 @@
|
||||
/* ipxwrapper - Address manipulation functions
|
||||
* Copyright (C) 2012 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 <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "addr.h"
|
||||
#include "common.h"
|
||||
|
||||
addr32_t addr32_in(const void *src)
|
||||
{
|
||||
addr32_t buf = 0;
|
||||
memcpy(&buf, src, 4);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* Write out a 32-bit address in network byte order. */
|
||||
void *addr32_out(void *dest, addr32_t src)
|
||||
{
|
||||
return memcpy(dest, &src, 4);
|
||||
}
|
||||
|
||||
/* Convert a 32-bit address to a string in the format XX:XX:XX:XX */
|
||||
char *addr32_string(char *buf, addr32_t addr)
|
||||
{
|
||||
unsigned char c[6];
|
||||
addr32_out(c, addr);
|
||||
|
||||
sprintf(
|
||||
buf,
|
||||
|
||||
"%02X:%02X:%02X:%02X",
|
||||
|
||||
(unsigned int)(c[0]),
|
||||
(unsigned int)(c[1]),
|
||||
(unsigned int)(c[2]),
|
||||
(unsigned int)(c[3])
|
||||
);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* Read a 32-bit network address from the registry.
|
||||
* Returns default_value upon failure.
|
||||
*/
|
||||
addr32_t reg_get_addr32(HKEY key, const char *name, addr32_t default_value)
|
||||
{
|
||||
unsigned char buf[4];
|
||||
reg_get_bin(key, name, buf, 4, &default_value);
|
||||
|
||||
return addr32_in(buf);
|
||||
}
|
||||
|
||||
addr48_t addr48_in(const void *src)
|
||||
{
|
||||
addr48_t buf = 0;
|
||||
memcpy(((char*)&buf) + 2, src, 6);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* Write out a 48-bit address in network byte order. */
|
||||
void *addr48_out(void *dest, addr48_t src)
|
||||
{
|
||||
return memcpy(dest, ((char*)&src) + 2, 6);
|
||||
}
|
||||
|
||||
/* Convert a 48-bit address to a string in the format XX:XX:XX:XX:XX:XX */
|
||||
char *addr48_string(char *buf, addr48_t addr)
|
||||
{
|
||||
unsigned char c[6];
|
||||
addr48_out(c, addr);
|
||||
|
||||
sprintf(
|
||||
buf,
|
||||
|
||||
"%02X:%02X:%02X:%02X:%02X:%02X",
|
||||
|
||||
(unsigned int)(c[0]),
|
||||
(unsigned int)(c[1]),
|
||||
(unsigned int)(c[2]),
|
||||
(unsigned int)(c[3]),
|
||||
(unsigned int)(c[4]),
|
||||
(unsigned int)(c[5])
|
||||
);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* Read a 48-bit network address from the registry.
|
||||
* Returns default_value upon failure.
|
||||
*/
|
||||
addr48_t reg_get_addr48(HKEY key, const char *name, addr48_t default_value)
|
||||
{
|
||||
unsigned char buf[6];
|
||||
reg_get_bin(key, name, buf, 6, &default_value);
|
||||
|
||||
return addr48_in(buf);
|
||||
}
|
||||
|
||||
/* Format an IPX address as a string.
|
||||
*
|
||||
* The socket number should be in network byte order and the supplied buffer
|
||||
* must be at least IPX_SADDR_SIZE bytes long.
|
||||
*/
|
||||
void ipx_to_string(char *buf, addr32_t net, addr48_t node, uint16_t sock)
|
||||
{
|
||||
addr32_string(buf, net);
|
||||
buf[17] = '/';
|
||||
|
||||
addr48_string(buf + 18, node);
|
||||
buf[29] = '/';
|
||||
|
||||
sprintf(buf + 30, "%hu", ntohs(sock));
|
||||
}
|
50
src/addr.h
Normal file
50
src/addr.h
Normal file
@ -0,0 +1,50 @@
|
||||
/* ipxwrapper - Address manipulation functions
|
||||
* Copyright (C) 2012 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_ADDR_H
|
||||
#define IPXWRAPPER_ADDR_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef uint32_t addr32_t;
|
||||
typedef uint64_t addr48_t;
|
||||
|
||||
#define ADDR32_STRING_SIZE 12
|
||||
|
||||
addr32_t addr32_in(const void *src);
|
||||
void *addr32_out(void *dest, addr32_t src);
|
||||
char *addr32_string(char *buf, addr32_t addr);
|
||||
|
||||
addr32_t reg_get_addr32(HKEY key, const char *name, addr32_t default_value);
|
||||
|
||||
#define ADDR48_STRING_SIZE 18
|
||||
|
||||
addr48_t addr48_in(const void *src);
|
||||
void *addr48_out(void *dest, addr48_t src);
|
||||
char *addr48_string(char *buf, addr48_t addr);
|
||||
|
||||
addr48_t reg_get_addr48(HKEY key, const char *name, addr48_t default_value);
|
||||
|
||||
#define IPX_SADDR_SIZE 36
|
||||
|
||||
#define IPX_STRING_ADDR(var, net, node, sock) \
|
||||
char var[IPX_SADDR_SIZE]; \
|
||||
ipx_to_string(var, net, node, sock);
|
||||
|
||||
void ipx_to_string(char *buf, addr32_t net, addr48_t node, uint16_t sock);
|
||||
|
||||
#endif /* !IPXWRAPPER_ADDR_H */
|
@ -26,8 +26,8 @@
|
||||
#include "common.h"
|
||||
|
||||
struct host_table_key {
|
||||
netnum_t netnum;
|
||||
nodenum_t nodenum;
|
||||
addr32_t netnum;
|
||||
addr48_t nodenum;
|
||||
};
|
||||
|
||||
struct host_table {
|
||||
@ -63,13 +63,13 @@ static void host_table_unlock(void)
|
||||
/* Search the host table for a node with the given net/node pair.
|
||||
* Returns NULL on failure.
|
||||
*/
|
||||
static host_table_t *host_table_find(const netnum_t net, const nodenum_t node)
|
||||
static host_table_t *host_table_find(addr32_t net, addr48_t node)
|
||||
{
|
||||
host_table_key_t key;
|
||||
memset(&key, 0, sizeof(key));
|
||||
|
||||
memcpy(key.netnum, net, sizeof(netnum_t));
|
||||
memcpy(key.nodenum, node, sizeof(nodenum_t));
|
||||
key.netnum = net;
|
||||
key.nodenum = node;
|
||||
|
||||
host_table_t *host;
|
||||
|
||||
@ -118,7 +118,7 @@ void addr_cache_cleanup(void)
|
||||
* Writes a sockaddr structure and addrlen to the provided pointers. Returns
|
||||
* true if a cached address was found, false otherwise.
|
||||
*/
|
||||
int addr_cache_get(SOCKADDR_STORAGE *addr, size_t *addrlen, netnum_t net, nodenum_t node, uint16_t sock)
|
||||
int addr_cache_get(SOCKADDR_STORAGE *addr, size_t *addrlen, addr32_t net, addr48_t node, uint16_t sock)
|
||||
{
|
||||
host_table_lock();
|
||||
|
||||
@ -146,7 +146,7 @@ int addr_cache_get(SOCKADDR_STORAGE *addr, size_t *addrlen, netnum_t net, nodenu
|
||||
* The given sockaddr structure will be copied and may be deallocated as soon as
|
||||
* this function returns.
|
||||
*/
|
||||
void addr_cache_set(const struct sockaddr *addr, size_t addrlen, netnum_t net, nodenum_t node, uint16_t sock)
|
||||
void addr_cache_set(const struct sockaddr *addr, size_t addrlen, addr32_t net, addr48_t node, uint16_t sock)
|
||||
{
|
||||
host_table_lock();
|
||||
|
||||
@ -168,8 +168,8 @@ void addr_cache_set(const struct sockaddr *addr, size_t addrlen, netnum_t net, n
|
||||
|
||||
memset(host, 0, sizeof(host_table_t));
|
||||
|
||||
memcpy(host->key.netnum, net, sizeof(netnum_t));
|
||||
memcpy(host->key.nodenum, node, sizeof(nodenum_t));
|
||||
host->key.netnum = net;
|
||||
host->key.nodenum = node;
|
||||
|
||||
HASH_ADD(hh, host_table, key, sizeof(host->key), host);
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ extern unsigned int addr_cache_ttl;
|
||||
void addr_cache_init(void);
|
||||
void addr_cache_cleanup(void);
|
||||
|
||||
int addr_cache_get(SOCKADDR_STORAGE *addr, size_t *addrlen, netnum_t net, nodenum_t node, uint16_t sock);
|
||||
void addr_cache_set(const struct sockaddr *addr, size_t addrlen, netnum_t net, nodenum_t node, uint16_t sock);
|
||||
int addr_cache_get(SOCKADDR_STORAGE *addr, size_t *addrlen, addr32_t net, addr48_t node, uint16_t sock);
|
||||
void addr_cache_set(const struct sockaddr *addr, size_t addrlen, addr32_t net, addr48_t node, uint16_t sock);
|
||||
|
||||
#endif /* !_ADDRCACHE_H */
|
||||
|
129
src/common.c
129
src/common.c
@ -21,8 +21,6 @@
|
||||
#include "common.h"
|
||||
#include "config.h"
|
||||
|
||||
HKEY regkey = NULL;
|
||||
|
||||
enum ipx_log_level min_log_level = LOG_INFO;
|
||||
|
||||
static const char *dll_names[] = {
|
||||
@ -45,82 +43,83 @@ const char *w32_error(DWORD errnum) {
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* Format an IPX address as a string.
|
||||
*
|
||||
* The socket number should be in network byte order and the supplied buffer
|
||||
* must be at least IPX_SADDR_SIZE bytes long.
|
||||
*/
|
||||
void ipx_to_string(char *buf, const netnum_t net, const nodenum_t node, uint16_t sock)
|
||||
HKEY reg_open_main(bool readwrite)
|
||||
{
|
||||
/* World's ugliest use of sprintf? */
|
||||
|
||||
sprintf(
|
||||
buf,
|
||||
|
||||
"%02X:%02X:%02X:%02X/%02X:%02X:%02X:%02X:%02X:%02X/%hu",
|
||||
|
||||
(unsigned int)(unsigned char)(net[0]),
|
||||
(unsigned int)(unsigned char)(net[1]),
|
||||
(unsigned int)(unsigned char)(net[2]),
|
||||
(unsigned int)(unsigned char)(net[3]),
|
||||
|
||||
(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]),
|
||||
|
||||
ntohs(sock)
|
||||
);
|
||||
return reg_open_subkey(HKEY_CURRENT_USER, "Software\\IPXWrapper", readwrite);
|
||||
}
|
||||
|
||||
BOOL reg_open(REGSAM access) {
|
||||
int err = RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\IPXWrapper", 0, access, ®key);
|
||||
HKEY reg_open_subkey(HKEY parent, const char *path, bool readwrite)
|
||||
{
|
||||
if(parent == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(err != ERROR_SUCCESS) {
|
||||
HKEY key;
|
||||
int err;
|
||||
|
||||
if(readwrite)
|
||||
{
|
||||
err = RegCreateKeyEx(parent, path, 0, NULL, 0, KEY_READ | KEY_WRITE, NULL, &key, NULL);
|
||||
}
|
||||
else{
|
||||
err = RegOpenKeyEx(parent, path, 0, KEY_READ, &key);
|
||||
}
|
||||
|
||||
if(err != ERROR_SUCCESS)
|
||||
{
|
||||
log_printf(LOG_ERROR, "Could not open registry: %s", w32_error(err));
|
||||
regkey = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
void reg_close(HKEY key)
|
||||
{
|
||||
if(key != NULL)
|
||||
{
|
||||
RegCloseKey(key);
|
||||
}
|
||||
}
|
||||
|
||||
bool reg_get_bin(HKEY key, const char *name, void *buf, size_t size, const void *default_value)
|
||||
{
|
||||
if(key != NULL)
|
||||
{
|
||||
DWORD bs = size;
|
||||
int err = RegQueryValueEx(key, name, NULL, NULL, (BYTE*)buf, &bs);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void reg_close(void) {
|
||||
if(regkey) {
|
||||
RegCloseKey(regkey);
|
||||
regkey = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
char reg_get_char(const char *val_name, char default_val) {
|
||||
char buf;
|
||||
return reg_get_bin(val_name, &buf, 1) == 1 ? buf : default_val;
|
||||
}
|
||||
|
||||
DWORD reg_get_bin(const char *val_name, void *buf, DWORD size) {
|
||||
if(!regkey) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int err = RegQueryValueEx(regkey, val_name, NULL, NULL, (BYTE*)buf, &size);
|
||||
|
||||
if(err != ERROR_SUCCESS) {
|
||||
if(err != ERROR_FILE_NOT_FOUND) {
|
||||
if(err == ERROR_SUCCESS)
|
||||
{
|
||||
if(bs == size)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else{
|
||||
log_printf(LOG_WARNING, "Registry value with incorrect size: %s", name);
|
||||
}
|
||||
}
|
||||
else if(err != ERROR_FILE_NOT_FOUND)
|
||||
{
|
||||
log_printf(LOG_ERROR, "Error reading registry value: %s", w32_error(err));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return size;
|
||||
if(default_value)
|
||||
{
|
||||
memcpy(buf, default_value, size);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
DWORD reg_get_dword(const char *val_name, DWORD default_val) {
|
||||
DWORD reg_get_dword(HKEY key, const char *name, DWORD default_value)
|
||||
{
|
||||
DWORD buf;
|
||||
return reg_get_bin(val_name, &buf, sizeof(buf)) == sizeof(buf) ? buf : default_val;
|
||||
reg_get_bin(key, name, &buf, sizeof(buf), &default_value);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
void load_dll(unsigned int dllnum) {
|
||||
|
28
src/common.h
28
src/common.h
@ -22,10 +22,14 @@
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define IPX_SADDR_SIZE 36
|
||||
#include "addr.h"
|
||||
|
||||
typedef unsigned char netnum_t[4];
|
||||
typedef unsigned char nodenum_t[6];
|
||||
#ifndef __cplusplus
|
||||
typedef unsigned char bool;
|
||||
|
||||
#define true 1
|
||||
#define false 0
|
||||
#endif
|
||||
|
||||
enum ipx_log_level {
|
||||
LOG_CALL = 1,
|
||||
@ -35,24 +39,16 @@ enum ipx_log_level {
|
||||
LOG_ERROR
|
||||
};
|
||||
|
||||
extern HKEY regkey;
|
||||
|
||||
extern enum ipx_log_level min_log_level;
|
||||
|
||||
const char *w32_error(DWORD errnum);
|
||||
|
||||
#define IPX_STRING_ADDR(var, net, node, sock) \
|
||||
char var[IPX_SADDR_SIZE]; \
|
||||
ipx_to_string(var, net, node, sock);
|
||||
HKEY reg_open_main(bool readwrite);
|
||||
HKEY reg_open_subkey(HKEY parent, const char *path, bool readwrite);
|
||||
void reg_close(HKEY key);
|
||||
|
||||
void ipx_to_string(char *buf, const netnum_t net, const nodenum_t node, uint16_t sock);
|
||||
|
||||
BOOL reg_open(REGSAM access);
|
||||
void reg_close(void);
|
||||
|
||||
char reg_get_char(const char *val_name, char default_val);
|
||||
DWORD reg_get_bin(const char *val_name, void *buf, DWORD size);
|
||||
DWORD reg_get_dword(const char *val_name, DWORD default_val);
|
||||
bool reg_get_bin(HKEY key, const char *name, void *buf, size_t size, const void *default_value);
|
||||
DWORD reg_get_dword(HKEY key, const char *name, DWORD default_value);
|
||||
|
||||
void load_dll(unsigned int dllnum);
|
||||
void unload_dlls(void);
|
||||
|
133
src/config.c
Normal file
133
src/config.c
Normal file
@ -0,0 +1,133 @@
|
||||
/* ipxwrapper - Configuration 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.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "common.h"
|
||||
|
||||
main_config_t get_main_config(void)
|
||||
{
|
||||
/* Defaults */
|
||||
|
||||
main_config_t config;
|
||||
|
||||
config.udp_port = DEFAULT_PORT;
|
||||
config.router_port = DEFAULT_ROUTER_PORT;
|
||||
config.w95_bug = true;
|
||||
config.bcast_all = false;
|
||||
config.src_filter = true;
|
||||
|
||||
HKEY reg = reg_open_main(false);
|
||||
DWORD version = reg_get_dword(reg, "config_version", 1);
|
||||
|
||||
if(version == 1)
|
||||
{
|
||||
struct v1_global_config reg_config;
|
||||
|
||||
if(reg_get_bin(reg, "global", ®_config, sizeof(reg_config), NULL))
|
||||
{
|
||||
config.udp_port = reg_config.udp_port;
|
||||
config.w95_bug = reg_config.w95_bug;
|
||||
config.bcast_all = reg_config.bcast_all;
|
||||
config.src_filter = reg_config.filter;
|
||||
}
|
||||
}
|
||||
else if(version == 2)
|
||||
{
|
||||
config.udp_port = reg_get_dword(reg, "port", config.udp_port);
|
||||
config.router_port = reg_get_dword(reg, "router_port", config.router_port);
|
||||
config.w95_bug = reg_get_dword(reg, "w95_bug", config.w95_bug);
|
||||
config.bcast_all = reg_get_dword(reg, "bcast_all", config.bcast_all);
|
||||
config.src_filter = reg_get_dword(reg, "src_filter", config.src_filter);
|
||||
}
|
||||
|
||||
reg_close(reg);
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
iface_config_t get_iface_config(addr48_t hwaddr)
|
||||
{
|
||||
char id[18];
|
||||
addr48_string(id, hwaddr);
|
||||
|
||||
addr32_t default_net = addr32_in((unsigned char[]){0x00, 0x00, 0x00, 0x01});
|
||||
|
||||
iface_config_t config;
|
||||
|
||||
HKEY reg = reg_open_main(false);
|
||||
DWORD version = reg_get_dword(reg, "config_version", 1);
|
||||
|
||||
if(version == 1)
|
||||
{
|
||||
struct v1_iface_config reg_config;
|
||||
|
||||
if(reg_get_bin(reg, id, ®_config, sizeof(reg_config), NULL))
|
||||
{
|
||||
config.netnum = addr32_in(reg_config.ipx_net);
|
||||
config.nodenum = addr48_in(reg_config.ipx_node);
|
||||
config.enabled = reg_config.enabled;
|
||||
|
||||
reg_close(reg);
|
||||
|
||||
return config;
|
||||
}
|
||||
}
|
||||
else if(version == 2)
|
||||
{
|
||||
HKEY iface_reg = reg_open_subkey(reg, id, false);
|
||||
|
||||
config.netnum = reg_get_addr32(iface_reg, "net", default_net);
|
||||
config.nodenum = reg_get_addr48(iface_reg, "node", hwaddr);
|
||||
config.enabled = reg_get_dword(iface_reg, "enabled", true);
|
||||
|
||||
reg_close(iface_reg);
|
||||
reg_close(reg);
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
config.netnum = default_net;
|
||||
config.nodenum = hwaddr;
|
||||
config.enabled = true;
|
||||
|
||||
reg_close(reg);
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
addr48_t get_primary_iface(void)
|
||||
{
|
||||
addr48_t primary = addr48_in((unsigned char[]){ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF });
|
||||
|
||||
HKEY reg = reg_open_main(false);
|
||||
DWORD version = reg_get_dword(reg, "config_version", 1);
|
||||
|
||||
if(version == 1)
|
||||
{
|
||||
/* TODO: Iterate... */
|
||||
}
|
||||
else if(version == 2)
|
||||
{
|
||||
primary = reg_get_addr48(reg, "primary", primary);
|
||||
}
|
||||
|
||||
reg_close(reg);
|
||||
|
||||
return primary;
|
||||
}
|
40
src/config.h
40
src/config.h
@ -19,22 +19,44 @@
|
||||
#define IPX_CONFIG_H
|
||||
|
||||
#define DEFAULT_PORT 54792
|
||||
#define DEFAULT_CONTROL_PORT 54793
|
||||
#define HOST_TTL 60
|
||||
#define DEFAULT_ROUTER_PORT 54793
|
||||
#define IFACE_TTL 10
|
||||
|
||||
struct reg_value {
|
||||
unsigned char ipx_net[4];
|
||||
unsigned char ipx_node[6];
|
||||
unsigned char enabled;
|
||||
unsigned char primary;
|
||||
} __attribute__((__packed__));
|
||||
#include "common.h"
|
||||
|
||||
struct reg_global {
|
||||
typedef struct main_config {
|
||||
uint16_t udp_port;
|
||||
uint16_t router_port;
|
||||
|
||||
bool w95_bug;
|
||||
bool bcast_all;
|
||||
bool src_filter;
|
||||
} main_config_t;
|
||||
|
||||
struct v1_global_config {
|
||||
uint16_t udp_port;
|
||||
unsigned char w95_bug;
|
||||
unsigned char bcast_all;
|
||||
unsigned char filter;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
typedef struct iface_config {
|
||||
addr32_t netnum;
|
||||
addr48_t nodenum;
|
||||
|
||||
bool enabled;
|
||||
} iface_config_t;
|
||||
|
||||
struct v1_iface_config {
|
||||
unsigned char ipx_net[4];
|
||||
unsigned char ipx_node[6];
|
||||
unsigned char enabled;
|
||||
unsigned char primary;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
main_config_t get_main_config(void);
|
||||
|
||||
iface_config_t get_iface_config(addr48_t hwaddr);
|
||||
addr48_t get_primary_iface();
|
||||
|
||||
#endif /* !IPX_CONFIG_H */
|
||||
|
@ -578,15 +578,18 @@ HRESULT WINAPI SPInit(LPSPINITDATA data) {
|
||||
}
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE me, DWORD why, LPVOID res) {
|
||||
if(why == DLL_PROCESS_ATTACH) {
|
||||
if(why == DLL_PROCESS_ATTACH)
|
||||
{
|
||||
log_open("ipxwrapper.log");
|
||||
|
||||
reg_open(KEY_QUERY_VALUE);
|
||||
HKEY reg = reg_open_main(false);
|
||||
|
||||
min_log_level = reg_get_dword("min_log_level", LOG_INFO);
|
||||
min_log_level = reg_get_dword(reg, "min_log_level", LOG_INFO);
|
||||
|
||||
reg_close();
|
||||
}else if(why == DLL_PROCESS_DETACH) {
|
||||
reg_close(reg);
|
||||
}
|
||||
else if(why == DLL_PROCESS_DETACH)
|
||||
{
|
||||
unload_dlls();
|
||||
log_close();
|
||||
}
|
||||
|
191
src/interface.c
191
src/interface.c
@ -22,75 +22,80 @@
|
||||
#include "common.h"
|
||||
#include "config.h"
|
||||
|
||||
/* Get virtual IPX interfaces
|
||||
* Select a single interface by setting ifnum >= 0
|
||||
/* Fetch a list of network interfaces available on the system.
|
||||
*
|
||||
* Returns a linked list of IP_ADAPTER_INFO structures, all allocated within a
|
||||
* single memory block beginning at the first node.
|
||||
*/
|
||||
struct ipx_interface *get_interfaces(int ifnum) {
|
||||
IP_ADAPTER_INFO *ifroot, tbuf;
|
||||
ULONG bufsize = sizeof(IP_ADAPTER_INFO);
|
||||
IP_ADAPTER_INFO *get_sys_interfaces(void)
|
||||
{
|
||||
IP_ADAPTER_INFO *ifroot = NULL, *ifptr;
|
||||
ULONG bufsize = sizeof(IP_ADAPTER_INFO) * 8;
|
||||
|
||||
int err = GetAdaptersInfo(&tbuf, &bufsize);
|
||||
if(err == ERROR_NO_DATA) {
|
||||
log_printf(LOG_WARNING, "No network interfaces detected!");
|
||||
return NULL;
|
||||
}else if(err != ERROR_SUCCESS && err != ERROR_BUFFER_OVERFLOW) {
|
||||
log_printf(LOG_ERROR, "Error fetching network interfaces: %s", w32_error(err));
|
||||
return NULL;
|
||||
}
|
||||
int err = ERROR_BUFFER_OVERFLOW;
|
||||
|
||||
if(!(ifroot = malloc(bufsize))) {
|
||||
log_printf(LOG_ERROR, "Out of memory! (Tried to allocate %u bytes)", (unsigned int)bufsize);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
err = GetAdaptersInfo(ifroot, &bufsize);
|
||||
if(err != ERROR_SUCCESS) {
|
||||
log_printf(LOG_ERROR, "Error fetching network interfaces: %s", w32_error(err));
|
||||
while(err == ERROR_BUFFER_OVERFLOW)
|
||||
{
|
||||
if(!(ifptr = realloc(ifroot, bufsize)))
|
||||
{
|
||||
log_printf(LOG_ERROR, "Couldn't allocate IP_ADAPTER_INFO structures!");
|
||||
break;
|
||||
}
|
||||
|
||||
ifroot = ifptr;
|
||||
|
||||
err = GetAdaptersInfo(ifroot, &bufsize);
|
||||
|
||||
if(err == ERROR_NO_DATA)
|
||||
{
|
||||
log_printf(LOG_WARNING, "No network interfaces detected!");
|
||||
break;
|
||||
}
|
||||
else if(err != ERROR_SUCCESS && err != ERROR_BUFFER_OVERFLOW)
|
||||
{
|
||||
log_printf(LOG_ERROR, "Error fetching network interfaces: %s", w32_error(err));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(err != ERROR_SUCCESS)
|
||||
{
|
||||
free(ifroot);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct ipx_interface *nics = NULL, *enic = NULL;
|
||||
return ifroot;
|
||||
}
|
||||
|
||||
/* Get virtual IPX interfaces
|
||||
* Select a single interface by setting ifnum >= 0
|
||||
*/
|
||||
ipx_interface_t *get_interfaces(int ifnum)
|
||||
{
|
||||
IP_ADAPTER_INFO *ifroot = get_sys_interfaces(), *ifptr;
|
||||
|
||||
IP_ADAPTER_INFO *ifptr = ifroot;
|
||||
addr48_t primary = get_primary_iface();
|
||||
|
||||
while(ifptr) {
|
||||
struct reg_value rv;
|
||||
int got_rv = 0;
|
||||
ipx_interface_t *nics = NULL;
|
||||
|
||||
for(ifptr = ifroot; ifptr; ifptr = ifptr->Next)
|
||||
{
|
||||
addr48_t hwaddr = addr48_in(ifptr->Address);
|
||||
|
||||
/* Format the hardware address as a hex string for fetching
|
||||
* settings from the registry.
|
||||
*/
|
||||
iface_config_t config = get_iface_config(hwaddr);
|
||||
|
||||
char vname[18];
|
||||
|
||||
sprintf(
|
||||
vname,
|
||||
|
||||
"%02X:%02X:%02X:%02X:%02X:%02X",
|
||||
|
||||
(unsigned int)(unsigned char)(ifptr->Address[0]),
|
||||
(unsigned int)(unsigned char)(ifptr->Address[1]),
|
||||
(unsigned int)(unsigned char)(ifptr->Address[2]),
|
||||
(unsigned int)(unsigned char)(ifptr->Address[3]),
|
||||
(unsigned int)(unsigned char)(ifptr->Address[4]),
|
||||
(unsigned int)(unsigned char)(ifptr->Address[5])
|
||||
);
|
||||
|
||||
if(reg_get_bin(vname, &rv, sizeof(rv)) == sizeof(rv)) {
|
||||
got_rv = 1;
|
||||
}
|
||||
|
||||
if(got_rv && !rv.enabled) {
|
||||
if(!config.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(LOG_ERROR, "Out of memory! (Tried to allocate %u bytes)", (unsigned int)sizeof(struct ipx_interface));
|
||||
if(!nnic)
|
||||
{
|
||||
log_printf(LOG_ERROR, "Couldn't allocate ipx_interface!");
|
||||
|
||||
free_interfaces(nics);
|
||||
return NULL;
|
||||
@ -100,78 +105,64 @@ struct ipx_interface *get_interfaces(int ifnum) {
|
||||
nnic->netmask = inet_addr(ifptr->IpAddressList.IpMask.String);
|
||||
nnic->bcast = nnic->ipaddr | ~nnic->netmask;
|
||||
|
||||
memcpy(nnic->hwaddr, ifptr->Address, 6);
|
||||
nnic->hwaddr = hwaddr;
|
||||
|
||||
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;
|
||||
nnic->ipx_net = config.netnum;
|
||||
nnic->ipx_node = config.nodenum;
|
||||
|
||||
/* Workaround for buggy versions of Hamachi that don't initialise
|
||||
* the interface hardware address correctly.
|
||||
*/
|
||||
|
||||
const unsigned char hamachi_bug[] = {0x7A, 0x79, 0x00, 0x00, 0x00, 0x00};
|
||||
unsigned char hamachi_bug[] = {0x7A, 0x79, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
if(strcmp(ifptr->Description, "Hamachi Network Interface") == 0 && memcmp(nnic->ipx_node, hamachi_bug, 6) == 0) {
|
||||
if(nnic->ipx_node == addr48_in(hamachi_bug))
|
||||
{
|
||||
log_printf(LOG_WARNING, "Invalid Hamachi interface detected, correcting node number");
|
||||
memcpy(nnic->ipx_node + 2, &(nnic->ipaddr), 4);
|
||||
}
|
||||
|
||||
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;
|
||||
addr32_out(hamachi_bug + 2, nnic->ipaddr);
|
||||
nnic->ipx_node = addr48_in(hamachi_bug);
|
||||
}
|
||||
|
||||
ifptr = ifptr->Next;
|
||||
if(nnic->hwaddr == primary)
|
||||
{
|
||||
/* Primary interface, insert at the start of the list */
|
||||
DL_PREPEND(nics, nnic);
|
||||
}
|
||||
else{
|
||||
DL_APPEND(nics, nnic);
|
||||
}
|
||||
}
|
||||
|
||||
free(ifroot);
|
||||
|
||||
/* Delete every entry in the NIC list except the requested one */
|
||||
if(ifnum >= 0) {
|
||||
|
||||
if(ifnum >= 0)
|
||||
{
|
||||
int this_ifnum = 0;
|
||||
ipx_interface_t *iface, *tmp;
|
||||
|
||||
while(nics && this_ifnum++ < ifnum) {
|
||||
struct ipx_interface *dnic = nics;
|
||||
nics = nics->next;
|
||||
|
||||
free(dnic);
|
||||
}
|
||||
|
||||
while(nics && nics->next) {
|
||||
struct ipx_interface *dnic = nics->next;
|
||||
nics->next = nics->next->next;
|
||||
|
||||
free(dnic);
|
||||
DL_FOREACH_SAFE(nics, iface, tmp)
|
||||
{
|
||||
if(this_ifnum++ != ifnum)
|
||||
{
|
||||
DL_DELETE(nics, iface);
|
||||
free(iface);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nics;
|
||||
}
|
||||
|
||||
void free_interfaces(struct ipx_interface *iface) {
|
||||
while(iface) {
|
||||
struct ipx_interface *del = iface;
|
||||
iface = iface->next;
|
||||
|
||||
free(del);
|
||||
void free_interfaces(ipx_interface_t *list)
|
||||
{
|
||||
ipx_interface_t *iface, *tmp;
|
||||
|
||||
DL_FOREACH_SAFE(list, iface, tmp)
|
||||
{
|
||||
DL_DELETE(list, iface);
|
||||
free(iface);
|
||||
}
|
||||
}
|
||||
|
@ -19,21 +19,27 @@
|
||||
#define IPXWRAPPER_INTERFACE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <utlist.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
typedef struct ipx_interface ipx_interface_t;
|
||||
|
||||
struct ipx_interface {
|
||||
uint32_t ipaddr;
|
||||
uint32_t netmask;
|
||||
uint32_t bcast;
|
||||
|
||||
unsigned char hwaddr[6];
|
||||
addr48_t hwaddr;
|
||||
|
||||
unsigned char ipx_net[4];
|
||||
unsigned char ipx_node[6];
|
||||
addr32_t ipx_net;
|
||||
addr48_t ipx_node;
|
||||
|
||||
struct ipx_interface *next;
|
||||
ipx_interface_t *prev;
|
||||
ipx_interface_t *next;
|
||||
};
|
||||
|
||||
struct ipx_interface *get_interfaces(int ifnum);
|
||||
void free_interfaces(struct ipx_interface *iface);
|
||||
ipx_interface_t *get_interfaces(int ifnum);
|
||||
void free_interfaces(ipx_interface_t *iface);
|
||||
|
||||
#endif /* !IPXWRAPPER_INTERFACE_H */
|
||||
|
@ -79,6 +79,9 @@ static RECT get_window_rect(HWND hwnd);
|
||||
static std::string w32_errmsg(DWORD errnum);
|
||||
static void die(std::string msg);
|
||||
|
||||
typedef struct v1_global_config reg_global;
|
||||
typedef struct v1_iface_config reg_value;
|
||||
|
||||
static iface_list nics;
|
||||
static reg_global global_conf;
|
||||
static HKEY regkey = NULL;
|
||||
@ -698,7 +701,7 @@ static void init_windows() {
|
||||
|
||||
DWORD port_buf;
|
||||
if(reg_read("control_port", &port_buf, sizeof(DWORD)) != sizeof(DWORD) || port_buf > 65535) {
|
||||
port_buf = DEFAULT_CONTROL_PORT;
|
||||
port_buf = DEFAULT_ROUTER_PORT;
|
||||
}
|
||||
|
||||
sprintf(port_s, "%hu", (uint16_t)port_buf);
|
||||
|
@ -42,7 +42,7 @@ struct ipaddr_list {
|
||||
|
||||
ipx_socket *sockets = NULL;
|
||||
SOCKET send_fd = -1;
|
||||
struct reg_global global_conf;
|
||||
main_config_t main_config;
|
||||
|
||||
struct rclient g_rclient;
|
||||
|
||||
@ -81,23 +81,14 @@ BOOL WINAPI DllMain(HINSTANCE me, DWORD why, LPVOID res) {
|
||||
_putenv(env);
|
||||
}
|
||||
|
||||
main_config = get_main_config();
|
||||
|
||||
addr_cache_init();
|
||||
|
||||
if(!rclient_init(&g_rclient)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
reg_open(KEY_QUERY_VALUE);
|
||||
|
||||
if(reg_get_bin("global", &global_conf, sizeof(global_conf)) != sizeof(global_conf)) {
|
||||
global_conf.udp_port = DEFAULT_PORT;
|
||||
global_conf.w95_bug = 1;
|
||||
global_conf.bcast_all = 0;
|
||||
global_conf.filter = 1;
|
||||
}
|
||||
|
||||
min_log_level = reg_get_dword("min_log_level", LOG_INFO);
|
||||
|
||||
init_cs(&sockets_cs);
|
||||
init_cs(&addrs_cs);
|
||||
|
||||
@ -148,8 +139,6 @@ BOOL WINAPI DllMain(HINSTANCE me, DWORD why, LPVOID res) {
|
||||
DeleteCriticalSection(&addrs_cs);
|
||||
DeleteCriticalSection(&sockets_cs);
|
||||
|
||||
reg_close();
|
||||
|
||||
addr_cache_cleanup();
|
||||
|
||||
unload_dlls();
|
||||
|
@ -98,7 +98,7 @@ struct ipx_host {
|
||||
|
||||
extern ipx_socket *sockets;
|
||||
extern SOCKET send_fd;
|
||||
extern struct reg_global global_conf;
|
||||
extern main_config_t main_config;
|
||||
extern struct rclient g_rclient;
|
||||
|
||||
ipx_socket *get_socket(SOCKET fd);
|
||||
|
@ -32,4 +32,3 @@ s_perror
|
||||
sethostname
|
||||
inet_addr
|
||||
WSHEnumProtocols:0
|
||||
ntohs:1
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include "common.h"
|
||||
#include "config.h"
|
||||
|
||||
struct reg_global global_conf;
|
||||
main_config_t main_config;
|
||||
|
||||
#define APPWM_TRAY (WM_APP+1)
|
||||
#define MNU_EXIT 101
|
||||
@ -36,14 +36,7 @@ static void show_menu(HWND hwnd);
|
||||
int main(int argc, char **argv) {
|
||||
log_open("ipxrouter.log");
|
||||
|
||||
reg_open(KEY_QUERY_VALUE);
|
||||
|
||||
if(reg_get_bin("global", &global_conf, sizeof(global_conf)) != sizeof(global_conf)) {
|
||||
global_conf.udp_port = DEFAULT_PORT;
|
||||
global_conf.w95_bug = 1;
|
||||
global_conf.bcast_all = 0;
|
||||
global_conf.filter = 1;
|
||||
}
|
||||
main_config = get_main_config();
|
||||
|
||||
WSADATA wsdata;
|
||||
int err = WSAStartup(MAKEWORD(2,0), &wsdata);
|
||||
@ -87,8 +80,6 @@ int main(int argc, char **argv) {
|
||||
|
||||
WSACleanup();
|
||||
|
||||
reg_close();
|
||||
|
||||
log_close();
|
||||
|
||||
return 0;
|
||||
|
28
src/router.c
28
src/router.c
@ -75,7 +75,7 @@ struct router_vars *router_init(BOOL global) {
|
||||
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = INADDR_ANY;
|
||||
addr.sin_port = htons(global_conf.udp_port);
|
||||
addr.sin_port = htons(main_config.udp_port);
|
||||
|
||||
if(bind(router->udp_sock, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
|
||||
log_printf(LOG_ERROR, "Error binding UDP socket: %s", w32_error(WSAGetLastError()));
|
||||
@ -114,7 +114,7 @@ struct router_vars *router_init(BOOL global) {
|
||||
}
|
||||
|
||||
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
addr.sin_port = htons(reg_get_dword("control_port", DEFAULT_CONTROL_PORT));
|
||||
addr.sin_port = htons(main_config.router_port);
|
||||
|
||||
if(bind(router->listener, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
|
||||
log_printf(LOG_ERROR, "Failed to bind TCP socket: %s", w32_error(WSAGetLastError()));
|
||||
@ -278,8 +278,8 @@ DWORD router_main(void *arg) {
|
||||
}
|
||||
|
||||
if(min_log_level <= LOG_DEBUG) {
|
||||
IPX_STRING_ADDR(src_addr, packet->src_net, packet->src_node, packet->src_socket);
|
||||
IPX_STRING_ADDR(dest_addr, packet->dest_net, packet->dest_node, packet->dest_socket);
|
||||
IPX_STRING_ADDR(src_addr, addr32_in(packet->src_net), addr48_in(packet->src_node), packet->src_socket);
|
||||
IPX_STRING_ADDR(dest_addr, addr32_in(packet->dest_net), addr48_in(packet->dest_node), packet->dest_socket);
|
||||
|
||||
log_printf(LOG_DEBUG, "Recieved packet from %s (%s) for %s", src_addr, inet_ntoa(addr.sin_addr), dest_addr);
|
||||
}
|
||||
@ -293,12 +293,12 @@ DWORD router_main(void *arg) {
|
||||
if(
|
||||
ra->local_port &&
|
||||
(ra->filter_ptype < 0 || ra->filter_ptype == packet->ptype) &&
|
||||
(memcmp(packet->dest_net, ra->addr.sa_netnum, 4) == 0 || (memcmp(packet->dest_net, f6, 4) == 0 && (ra->flags & IPX_BROADCAST || !global_conf.w95_bug) && ra->flags & IPX_RECV_BCAST)) &&
|
||||
(memcmp(packet->dest_node, ra->addr.sa_nodenum, 6) == 0 || (memcmp(packet->dest_node, f6, 6) == 0 && (ra->flags & IPX_BROADCAST || !global_conf.w95_bug) && ra->flags & IPX_RECV_BCAST)) &&
|
||||
(memcmp(packet->dest_net, ra->addr.sa_netnum, 4) == 0 || (memcmp(packet->dest_net, f6, 4) == 0 && (ra->flags & IPX_BROADCAST || !main_config.w95_bug) && ra->flags & IPX_RECV_BCAST)) &&
|
||||
(memcmp(packet->dest_node, ra->addr.sa_nodenum, 6) == 0 || (memcmp(packet->dest_node, f6, 6) == 0 && (ra->flags & IPX_BROADCAST || !main_config.w95_bug) && ra->flags & IPX_RECV_BCAST)) &&
|
||||
packet->dest_socket == ra->addr.sa_socket &&
|
||||
|
||||
/* Check source IP is within correct subnet */
|
||||
((ra->ipaddr & ra->netmask) == (addr.sin_addr.s_addr & ra->netmask) || !global_conf.filter) &&
|
||||
((ra->ipaddr & ra->netmask) == (addr.sin_addr.s_addr & ra->netmask) || !main_config.src_filter) &&
|
||||
|
||||
/* Check source address matches remote_addr if set */
|
||||
(ra->remote_addr.sa_family == AF_UNSPEC || (memcmp(ra->remote_addr.sa_netnum, packet->src_net, 4) == 0 && memcmp(ra->remote_addr.sa_nodenum, packet->src_node, 6) == 0))
|
||||
@ -337,12 +337,14 @@ static int router_bind(struct router_vars *router, SOCKET control, SOCKET sock,
|
||||
*/
|
||||
|
||||
struct ipx_interface *ifaces = get_interfaces(-1), *iface;
|
||||
unsigned char z6[] = {0,0,0,0,0,0};
|
||||
|
||||
addr32_t sa_netnum = addr32_in(addr->sa_netnum);
|
||||
addr48_t sa_nodenum = addr48_in(addr->sa_nodenum);
|
||||
|
||||
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)
|
||||
(sa_netnum == iface->ipx_net || sa_netnum == 0)
|
||||
&& (sa_nodenum == iface->ipx_node || sa_nodenum == 0)
|
||||
) {
|
||||
break;
|
||||
}
|
||||
@ -357,8 +359,8 @@ static int router_bind(struct router_vars *router, SOCKET control, SOCKET sock,
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(addr->sa_netnum, iface->ipx_net, 4);
|
||||
memcpy(addr->sa_nodenum, iface->ipx_node, 6);
|
||||
addr32_out(addr->sa_netnum, iface->ipx_net);
|
||||
addr48_out(addr->sa_nodenum, iface->ipx_node);
|
||||
|
||||
*nic_bcast = iface->bcast;
|
||||
|
||||
@ -676,7 +678,7 @@ BOOL rclient_start(struct rclient *rclient) {
|
||||
struct sockaddr_in addr;
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
addr.sin_port = htons(reg_get_dword("control_port", DEFAULT_CONTROL_PORT));
|
||||
addr.sin_port = htons(main_config.router_port);
|
||||
|
||||
if(connect(rclient->sock, (struct sockaddr*)&addr, sizeof(addr)) == 0) {
|
||||
return TRUE;
|
||||
|
@ -22,15 +22,18 @@
|
||||
#include "common.h"
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE me, DWORD why, LPVOID res) {
|
||||
if(why == DLL_PROCESS_ATTACH) {
|
||||
if(why == DLL_PROCESS_ATTACH)
|
||||
{
|
||||
log_open("ipxwrapper.log");
|
||||
|
||||
reg_open(KEY_QUERY_VALUE);
|
||||
HKEY reg = reg_open_main(false);
|
||||
|
||||
min_log_level = reg_get_dword("min_log_level", LOG_INFO);
|
||||
min_log_level = reg_get_dword(reg, "min_log_level", LOG_INFO);
|
||||
|
||||
reg_close();
|
||||
}else if(why == DLL_PROCESS_DETACH) {
|
||||
reg_close(reg);
|
||||
}
|
||||
else if(why == DLL_PROCESS_DETACH)
|
||||
{
|
||||
unload_dlls();
|
||||
log_close();
|
||||
}
|
||||
|
@ -240,7 +240,7 @@ int WSAAPI bind(SOCKET fd, const struct sockaddr *addr, int addrlen) {
|
||||
|
||||
memcpy(&ipxaddr, addr, sizeof(ipxaddr));
|
||||
|
||||
IPX_STRING_ADDR(req_addr_s, ipxaddr.sa_netnum, ipxaddr.sa_nodenum, ipxaddr.sa_socket);
|
||||
IPX_STRING_ADDR(req_addr_s, addr32_in(ipxaddr.sa_netnum), addr48_in(ipxaddr.sa_nodenum), ipxaddr.sa_socket);
|
||||
|
||||
log_printf(LOG_INFO, "bind(%d, %s)", fd, req_addr_s);
|
||||
|
||||
@ -253,7 +253,7 @@ int WSAAPI bind(SOCKET fd, const struct sockaddr *addr, int addrlen) {
|
||||
RETURN(-1);
|
||||
}
|
||||
|
||||
IPX_STRING_ADDR(got_addr_s, ipxaddr.sa_netnum, ipxaddr.sa_nodenum, ipxaddr.sa_socket);
|
||||
IPX_STRING_ADDR(got_addr_s, addr32_in(ipxaddr.sa_netnum), addr48_in(ipxaddr.sa_nodenum), ipxaddr.sa_socket);
|
||||
|
||||
log_printf(LOG_INFO, "bind address: %s", got_addr_s);
|
||||
|
||||
@ -362,7 +362,7 @@ static int recv_packet(ipx_socket *sockptr, char *buf, int bufsize, int flags, s
|
||||
|
||||
if(min_log_level <= LOG_DEBUG)
|
||||
{
|
||||
IPX_STRING_ADDR(addr_s, packet->src_net, packet->src_node, packet->src_socket);
|
||||
IPX_STRING_ADDR(addr_s, addr32_in(packet->src_net), addr48_in(packet->src_node), packet->src_socket);
|
||||
|
||||
log_printf(LOG_DEBUG, "Received packet from %s", addr_s);
|
||||
}
|
||||
@ -372,9 +372,9 @@ static int recv_packet(ipx_socket *sockptr, char *buf, int bufsize, int flags, s
|
||||
struct sockaddr_in real_addr;
|
||||
real_addr.sin_family = AF_INET;
|
||||
real_addr.sin_addr.s_addr = rp_header->src_ipaddr;
|
||||
real_addr.sin_port = htons(global_conf.udp_port);
|
||||
real_addr.sin_port = htons(main_config.udp_port);
|
||||
|
||||
addr_cache_set((struct sockaddr*)&real_addr, sizeof(real_addr), packet->src_net, packet->src_node, 0);
|
||||
addr_cache_set((struct sockaddr*)&real_addr, sizeof(real_addr), addr32_in(packet->src_net), addr48_in(packet->src_node), 0);
|
||||
|
||||
if(addr) {
|
||||
addr->sa_family = AF_IPX;
|
||||
@ -530,8 +530,8 @@ int WSAAPI getsockopt(SOCKET fd, int level, int optname, char FAR *optval, int F
|
||||
RETURN_WSA(ERROR_NO_DATA, -1);
|
||||
}
|
||||
|
||||
memcpy(ipxdata->netnum, nic->ipx_net, 4);
|
||||
memcpy(ipxdata->nodenum, nic->ipx_node, 6);
|
||||
addr32_out(ipxdata->netnum, nic->ipx_net);
|
||||
addr48_out(ipxdata->nodenum, nic->ipx_node);
|
||||
|
||||
/* TODO: LAN/WAN detection, link speed detection */
|
||||
ipxdata->wan = FALSE;
|
||||
@ -777,15 +777,15 @@ int WSAAPI sendto(SOCKET fd, const char *buf, int len, int flags, const struct s
|
||||
SOCKADDR_STORAGE send_addr;
|
||||
size_t addrlen;
|
||||
|
||||
if(!addr_cache_get(&send_addr, &addrlen, packet->dest_net, packet->dest_node, packet->dest_socket))
|
||||
if(!addr_cache_get(&send_addr, &addrlen, addr32_in(packet->dest_net), addr48_in(packet->dest_node), packet->dest_socket))
|
||||
{
|
||||
/* No cached address. Send using broadcast. */
|
||||
|
||||
struct sockaddr_in *bcast = (struct sockaddr_in*)&send_addr;
|
||||
|
||||
bcast->sin_family = AF_INET;
|
||||
bcast->sin_addr.s_addr = (global_conf.bcast_all ? INADDR_BROADCAST : sockptr->nic_bcast);
|
||||
bcast->sin_port = htons(global_conf.udp_port);
|
||||
bcast->sin_addr.s_addr = (main_config.bcast_all ? INADDR_BROADCAST : sockptr->nic_bcast);
|
||||
bcast->sin_port = htons(main_config.udp_port);
|
||||
|
||||
addrlen = sizeof(*bcast);
|
||||
}
|
||||
@ -795,7 +795,7 @@ int WSAAPI sendto(SOCKET fd, const char *buf, int len, int flags, const struct s
|
||||
|
||||
struct sockaddr_in *v4 = (struct sockaddr_in*)&send_addr;
|
||||
|
||||
IPX_STRING_ADDR(addr_s, packet->dest_net, packet->dest_node, packet->dest_socket);
|
||||
IPX_STRING_ADDR(addr_s, addr32_in(packet->dest_net), addr48_in(packet->dest_node), packet->dest_socket);
|
||||
|
||||
log_printf(LOG_DEBUG, "Sending packet to %s (%s)", addr_s, inet_ntoa(v4->sin_addr));
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user