mirror of
https://github.com/solemnwarning/ipxwrapper
synced 2024-12-30 16:45:37 +01:00
Implemented wildcard interface support.
This commit is contained in:
parent
2aa64787ab
commit
6c1ab421da
@ -97,7 +97,7 @@ addr32_t reg_get_addr32(HKEY key, const char *name, addr32_t default_value)
|
|||||||
{
|
{
|
||||||
unsigned char buf[4], default_buf[4];
|
unsigned char buf[4], default_buf[4];
|
||||||
|
|
||||||
addr48_out(default_buf, default_value);
|
addr32_out(default_buf, default_value);
|
||||||
reg_get_bin(key, name, buf, 4, default_buf);
|
reg_get_bin(key, name, buf, 4, default_buf);
|
||||||
|
|
||||||
return addr32_in(buf);
|
return addr32_in(buf);
|
||||||
|
70
src/config.c
70
src/config.c
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "interface.h"
|
||||||
|
|
||||||
main_config_t get_main_config(void)
|
main_config_t get_main_config(void)
|
||||||
{
|
{
|
||||||
@ -37,24 +38,6 @@ main_config_t get_main_config(void)
|
|||||||
|
|
||||||
config.iface_mode = reg_get_dword(reg, "iface_mode", IFACE_MODE_ALL);
|
config.iface_mode = reg_get_dword(reg, "iface_mode", IFACE_MODE_ALL);
|
||||||
|
|
||||||
config.single_netnum = reg_get_addr32(reg, "single_netnum", addr32_in((unsigned char[]){0x00, 0x00, 0x00, 0x01}));
|
|
||||||
config.single_nodenum = reg_get_addr48(reg, "single_nodenum", 0);
|
|
||||||
|
|
||||||
if(config.single_nodenum == 0)
|
|
||||||
{
|
|
||||||
/* Generate a random node number and store it in the registry
|
|
||||||
* for persistence.
|
|
||||||
*/
|
|
||||||
|
|
||||||
config.single_nodenum = gen_random_mac();
|
|
||||||
|
|
||||||
HKEY wreg = reg_open_main(true);
|
|
||||||
|
|
||||||
reg_set_addr48(wreg, "single_nodenum", config.single_nodenum);
|
|
||||||
|
|
||||||
reg_close(wreg);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(version == 1)
|
if(version == 1)
|
||||||
{
|
{
|
||||||
struct v1_global_config reg_config;
|
struct v1_global_config reg_config;
|
||||||
@ -92,8 +75,6 @@ bool set_main_config(const main_config_t *config)
|
|||||||
HKEY reg = reg_open_main(true);
|
HKEY reg = reg_open_main(true);
|
||||||
|
|
||||||
bool ok = reg_set_dword(reg, "iface_mode", config->iface_mode)
|
bool ok = reg_set_dword(reg, "iface_mode", config->iface_mode)
|
||||||
&& reg_set_addr32(reg, "single_netnum", config->single_netnum)
|
|
||||||
&& reg_set_addr48(reg, "single_nodenum", config->single_nodenum)
|
|
||||||
|
|
||||||
&& reg_set_dword(reg, "port", config->udp_port)
|
&& reg_set_dword(reg, "port", config->udp_port)
|
||||||
&& reg_set_dword(reg, "router_port", config->router_port)
|
&& reg_set_dword(reg, "router_port", config->router_port)
|
||||||
@ -115,15 +96,23 @@ iface_config_t get_iface_config(addr48_t hwaddr)
|
|||||||
char id[18];
|
char id[18];
|
||||||
addr48_string(id, hwaddr);
|
addr48_string(id, hwaddr);
|
||||||
|
|
||||||
addr32_t default_net = addr32_in((unsigned char[]){0x00, 0x00, 0x00, 0x01});
|
iface_config_t config = {
|
||||||
|
.netnum = addr32_in((unsigned char[]){0x00, 0x00, 0x00, 0x01}),
|
||||||
|
.nodenum = hwaddr,
|
||||||
|
|
||||||
|
.enabled = true
|
||||||
|
};
|
||||||
|
|
||||||
iface_config_t config;
|
HKEY reg = reg_open_main(false);
|
||||||
|
HKEY ifreg = reg_open_subkey(reg, id, false);
|
||||||
|
|
||||||
HKEY reg = reg_open_main(false);
|
if(ifreg)
|
||||||
DWORD version = reg_get_dword(reg, "config_version", 1);
|
|
||||||
|
|
||||||
if(version == 1)
|
|
||||||
{
|
{
|
||||||
|
config.netnum = reg_get_addr32(ifreg, "net", config.netnum);
|
||||||
|
config.nodenum = reg_get_addr48(ifreg, "node", config.nodenum);
|
||||||
|
config.enabled = reg_get_dword(ifreg, "enabled", config.enabled);
|
||||||
|
}
|
||||||
|
else{
|
||||||
struct v1_iface_config reg_config;
|
struct v1_iface_config reg_config;
|
||||||
|
|
||||||
if(reg_get_bin(reg, id, ®_config, sizeof(reg_config), NULL))
|
if(reg_get_bin(reg, id, ®_config, sizeof(reg_config), NULL))
|
||||||
@ -131,30 +120,21 @@ iface_config_t get_iface_config(addr48_t hwaddr)
|
|||||||
config.netnum = addr32_in(reg_config.ipx_net);
|
config.netnum = addr32_in(reg_config.ipx_net);
|
||||||
config.nodenum = addr48_in(reg_config.ipx_node);
|
config.nodenum = addr48_in(reg_config.ipx_node);
|
||||||
config.enabled = reg_config.enabled;
|
config.enabled = reg_config.enabled;
|
||||||
|
|
||||||
reg_close(reg);
|
|
||||||
|
|
||||||
return config;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(version == 2)
|
|
||||||
|
if(hwaddr == WILDCARD_IFACE_HWADDR && config.nodenum == hwaddr)
|
||||||
{
|
{
|
||||||
HKEY iface_reg = reg_open_subkey(reg, id, false);
|
/* Generate a random node number for the wildcard interface and
|
||||||
|
* store it in the registry for persistence.
|
||||||
|
*/
|
||||||
|
|
||||||
config.netnum = reg_get_addr32(iface_reg, "net", default_net);
|
config.nodenum = gen_random_mac();
|
||||||
config.nodenum = reg_get_addr48(iface_reg, "node", hwaddr);
|
|
||||||
config.enabled = reg_get_dword(iface_reg, "enabled", true);
|
|
||||||
|
|
||||||
reg_close(iface_reg);
|
set_iface_config(hwaddr, &config);
|
||||||
reg_close(reg);
|
|
||||||
|
|
||||||
return config;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
config.netnum = default_net;
|
reg_close(ifreg);
|
||||||
config.nodenum = hwaddr;
|
|
||||||
config.enabled = true;
|
|
||||||
|
|
||||||
reg_close(reg);
|
reg_close(reg);
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
@ -169,8 +149,8 @@ bool set_iface_config(addr48_t hwaddr, const iface_config_t *config)
|
|||||||
HKEY ifreg = reg_open_subkey(reg, id, true);
|
HKEY ifreg = reg_open_subkey(reg, id, true);
|
||||||
|
|
||||||
bool ok = reg_set_addr32(ifreg, "net", config->netnum)
|
bool ok = reg_set_addr32(ifreg, "net", config->netnum)
|
||||||
&& reg_set_addr32(ifreg, "node", config->nodenum)
|
&& reg_set_addr48(ifreg, "node", config->nodenum)
|
||||||
&& reg_set_addr32(ifreg, "enabled", config->enabled);
|
&& reg_set_dword(ifreg, "enabled", config->enabled);
|
||||||
|
|
||||||
reg_close(ifreg);
|
reg_close(ifreg);
|
||||||
reg_close(reg);
|
reg_close(reg);
|
||||||
|
@ -58,9 +58,6 @@ typedef struct main_config {
|
|||||||
enum ipx_log_level log_level;
|
enum ipx_log_level log_level;
|
||||||
|
|
||||||
int iface_mode;
|
int iface_mode;
|
||||||
|
|
||||||
addr32_t single_netnum;
|
|
||||||
addr48_t single_nodenum;
|
|
||||||
} main_config_t;
|
} main_config_t;
|
||||||
|
|
||||||
struct v1_global_config {
|
struct v1_global_config {
|
||||||
|
@ -76,6 +76,46 @@ IP_ADAPTER_INFO *load_sys_interfaces(void)
|
|||||||
return ifroot;
|
return ifroot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Allocate and initialise a new ipx_interface structure.
|
||||||
|
* Returns NULL on malloc failure.
|
||||||
|
*/
|
||||||
|
static ipx_interface_t *_new_iface(addr32_t net, addr48_t node)
|
||||||
|
{
|
||||||
|
ipx_interface_t *iface = malloc(sizeof(ipx_interface_t));
|
||||||
|
if(!iface)
|
||||||
|
{
|
||||||
|
log_printf(LOG_ERROR, "Cannot allocate ipx_interface!");
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(iface, 0, sizeof(*iface));
|
||||||
|
|
||||||
|
iface->ipx_net = net;
|
||||||
|
iface->ipx_node = node;
|
||||||
|
|
||||||
|
return iface;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add an IP address to an ipx_interface structure.
|
||||||
|
* Returns false on malloc failure.
|
||||||
|
*/
|
||||||
|
static bool _push_addr(ipx_interface_t *iface, uint32_t ipaddr, uint32_t netmask)
|
||||||
|
{
|
||||||
|
ipx_interface_ip_t *addr = malloc(sizeof(ipx_interface_ip_t));
|
||||||
|
if(!addr)
|
||||||
|
{
|
||||||
|
log_printf(LOG_ERROR, "Couldn't allocate ipx_interface_ip!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
addr->ipaddr = ipaddr;
|
||||||
|
addr->netmask = netmask;
|
||||||
|
addr->bcast = ipaddr | (~netmask);
|
||||||
|
|
||||||
|
DL_APPEND(iface->ipaddr, addr);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/* Load a list of virtual IPX interfaces. */
|
/* Load a list of virtual IPX interfaces. */
|
||||||
ipx_interface_t *load_ipx_interfaces(void)
|
ipx_interface_t *load_ipx_interfaces(void)
|
||||||
{
|
{
|
||||||
@ -85,6 +125,32 @@ ipx_interface_t *load_ipx_interfaces(void)
|
|||||||
|
|
||||||
ipx_interface_t *nics = NULL;
|
ipx_interface_t *nics = NULL;
|
||||||
|
|
||||||
|
iface_config_t wc_config = get_iface_config(WILDCARD_IFACE_HWADDR);
|
||||||
|
|
||||||
|
if(wc_config.enabled)
|
||||||
|
{
|
||||||
|
/* Initialise wildcard interface. */
|
||||||
|
|
||||||
|
ipx_interface_t *wc_iface = _new_iface(wc_config.netnum, wc_config.nodenum);
|
||||||
|
if(!wc_iface)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Use 0.0.0.0/0 as the IP/network of the wildcard interface
|
||||||
|
* to broadcast to 255.255.255.255 and match packets from any
|
||||||
|
* address.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if(!_push_addr(wc_iface, 0, 0))
|
||||||
|
{
|
||||||
|
free_ipx_interface(wc_iface);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
DL_APPEND(nics, wc_iface);
|
||||||
|
}
|
||||||
|
|
||||||
for(ifptr = ifroot; ifptr; ifptr = ifptr->Next)
|
for(ifptr = ifroot; ifptr; ifptr = ifptr->Next)
|
||||||
{
|
{
|
||||||
addr48_t hwaddr = addr48_in(ifptr->Address);
|
addr48_t hwaddr = addr48_in(ifptr->Address);
|
||||||
@ -99,16 +165,16 @@ ipx_interface_t *load_ipx_interfaces(void)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ipx_interface_t *iface = malloc(sizeof(ipx_interface_t));
|
ipx_interface_t *iface = _new_iface(config.netnum, config.nodenum);
|
||||||
if(!iface)
|
if(!iface)
|
||||||
{
|
{
|
||||||
log_printf(LOG_ERROR, "Couldn't allocate ipx_interface!");
|
|
||||||
|
|
||||||
free_ipx_interface_list(&nics);
|
free_ipx_interface_list(&nics);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
iface->ipaddr = NULL;
|
/* Iterate over the interface IP address list and add them to
|
||||||
|
* the ipx_interface structure.
|
||||||
|
*/
|
||||||
|
|
||||||
IP_ADDR_STRING *ip_ptr = &(ifptr->IpAddressList);
|
IP_ADDR_STRING *ip_ptr = &(ifptr->IpAddressList);
|
||||||
|
|
||||||
@ -126,29 +192,15 @@ ipx_interface_t *load_ipx_interfaces(void)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ipx_interface_ip_t *addr = malloc(sizeof(ipx_interface_ip_t));
|
if(!_push_addr(iface, ipaddr, netmask))
|
||||||
if(!addr)
|
|
||||||
{
|
{
|
||||||
log_printf(LOG_ERROR, "Couldn't allocate ipx_interface_ip!");
|
|
||||||
|
|
||||||
free_ipx_interface(iface);
|
free_ipx_interface(iface);
|
||||||
free_ipx_interface_list(&nics);
|
free_ipx_interface_list(&nics);
|
||||||
|
|
||||||
continue;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
addr->ipaddr = ipaddr;
|
|
||||||
addr->netmask = netmask;
|
|
||||||
addr->bcast = ipaddr | (~netmask);
|
|
||||||
|
|
||||||
DL_APPEND(iface->ipaddr, addr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
iface->hwaddr = hwaddr;
|
|
||||||
|
|
||||||
iface->ipx_net = config.netnum;
|
|
||||||
iface->ipx_node = config.nodenum;
|
|
||||||
|
|
||||||
/* Workaround for buggy versions of Hamachi that don't initialise
|
/* Workaround for buggy versions of Hamachi that don't initialise
|
||||||
* the interface hardware address correctly.
|
* the interface hardware address correctly.
|
||||||
*/
|
*/
|
||||||
@ -163,7 +215,7 @@ ipx_interface_t *load_ipx_interfaces(void)
|
|||||||
iface->ipx_node = addr48_in(hamachi_bug);
|
iface->ipx_node = addr48_in(hamachi_bug);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(iface->hwaddr == primary)
|
if(hwaddr == primary)
|
||||||
{
|
{
|
||||||
/* Primary interface, insert at the start of the list */
|
/* Primary interface, insert at the start of the list */
|
||||||
DL_PREPEND(nics, iface);
|
DL_PREPEND(nics, iface);
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#ifndef IPXWRAPPER_INTERFACE_H
|
#ifndef IPXWRAPPER_INTERFACE_H
|
||||||
#define IPXWRAPPER_INTERFACE_H
|
#define IPXWRAPPER_INTERFACE_H
|
||||||
|
|
||||||
|
#include <iphlpapi.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <utlist.h>
|
#include <utlist.h>
|
||||||
|
|
||||||
@ -27,6 +28,8 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define WILDCARD_IFACE_HWADDR addr48_in((unsigned char[]){0x00,0x00,0x00,0x00,0x00,0x00})
|
||||||
|
|
||||||
typedef struct ipx_interface_ip ipx_interface_ip_t;
|
typedef struct ipx_interface_ip ipx_interface_ip_t;
|
||||||
|
|
||||||
struct ipx_interface_ip {
|
struct ipx_interface_ip {
|
||||||
@ -41,8 +44,6 @@ struct ipx_interface_ip {
|
|||||||
typedef struct ipx_interface ipx_interface_t;
|
typedef struct ipx_interface ipx_interface_t;
|
||||||
|
|
||||||
struct ipx_interface {
|
struct ipx_interface {
|
||||||
addr48_t hwaddr;
|
|
||||||
|
|
||||||
addr32_t ipx_net;
|
addr32_t ipx_net;
|
||||||
addr48_t ipx_node;
|
addr48_t ipx_node;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user