diff --git a/src/addr.c b/src/addr.c index 6e83f96..7589914 100644 --- a/src/addr.c +++ b/src/addr.c @@ -95,12 +95,25 @@ bool addr32_from_string(addr32_t *dest, const char *src) */ 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); + unsigned char buf[4], default_buf[4]; + + addr48_out(default_buf, default_value); + reg_get_bin(key, name, buf, 4, default_buf); return addr32_in(buf); } +/* Store a 32-bit network address in the registry. + * Returns true on success, false on failure. +*/ +bool reg_set_addr32(HKEY key, const char *name, addr32_t value) +{ + unsigned char buf[4]; + addr32_out(buf, value); + + return reg_set_bin(key, name, buf, sizeof(buf)); +} + addr48_t addr48_in(const void *src) { addr48_t buf = 0; @@ -150,12 +163,25 @@ bool addr48_from_string(addr48_t *dest, const char *src) */ 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); + unsigned char buf[6], default_buf[6]; + + addr48_out(default_buf, default_value); + reg_get_bin(key, name, buf, 6, default_buf); return addr48_in(buf); } +/* Store a 48-bit network address in the registry. + * Returns true on success, false on failure. +*/ +bool reg_set_addr48(HKEY key, const char *name, addr48_t value) +{ + unsigned char buf[6]; + addr48_out(buf, value); + + return reg_set_bin(key, name, buf, sizeof(buf)); +} + /* Format an IPX address as a string. * * The socket number should be in network byte order and the supplied buffer @@ -171,3 +197,27 @@ void ipx_to_string(char *buf, addr32_t net, addr48_t node, uint16_t sock) sprintf(buf + 30, "%hu", ntohs(sock)); } + +/* Generate a (probably) unique locally-administered MAC address. */ +addr48_t gen_random_mac() +{ + static bool seeded = false; + + if(!seeded) + { + srand(GetTickCount()); + seeded = true; + } + + unsigned char addr[6]; + unsigned int i; + + for(i = 0; i < 6; i++) + { + addr[i] = (rand() % 0xFF); + } + + addr[0] |= 0x02; + + return addr48_in(addr); +} diff --git a/src/addr.h b/src/addr.h index 723c623..4e935c6 100644 --- a/src/addr.h +++ b/src/addr.h @@ -37,6 +37,7 @@ char *addr32_string(char *buf, addr32_t addr); bool addr32_from_string(addr32_t *dest, const char *src); addr32_t reg_get_addr32(HKEY key, const char *name, addr32_t default_value); +bool reg_set_addr32(HKEY key, const char *name, addr32_t value); #define ADDR48_STRING_SIZE 18 @@ -47,6 +48,7 @@ char *addr48_string(char *buf, addr48_t addr); bool addr48_from_string(addr48_t *dest, const char *src); addr48_t reg_get_addr48(HKEY key, const char *name, addr48_t default_value); +bool reg_set_addr48(HKEY key, const char *name, addr48_t value); #define IPX_SADDR_SIZE 36 @@ -56,6 +58,8 @@ addr48_t reg_get_addr48(HKEY key, const char *name, addr48_t default_value); void ipx_to_string(char *buf, addr32_t net, addr48_t node, uint16_t sock); +addr48_t gen_random_mac(); + #ifdef __cplusplus } #endif diff --git a/src/common.c b/src/common.c index d8bcc80..d5de5f1 100644 --- a/src/common.c +++ b/src/common.c @@ -114,6 +114,24 @@ bool reg_get_bin(HKEY key, const char *name, void *buf, size_t size, const void return false; } +bool reg_set_bin(HKEY key, const char *name, void *buf, size_t size) +{ + if(key != NULL) + { + int err = RegSetValueEx(key, name, 0, REG_BINARY, (BYTE*)buf, size); + + if(err == ERROR_SUCCESS) + { + return true; + } + else{ + log_printf(LOG_ERROR, "Error writing registry value: %s", w32_error(err)); + } + } + + return false; +} + DWORD reg_get_dword(HKEY key, const char *name, DWORD default_value) { DWORD buf; @@ -122,6 +140,24 @@ DWORD reg_get_dword(HKEY key, const char *name, DWORD default_value) return buf; } +bool reg_set_dword(HKEY key, const char *name, DWORD value) +{ + if(key != NULL) + { + int err = RegSetValueEx(key, name, 0, REG_DWORD, (BYTE*)&value, sizeof(value)); + + if(err == ERROR_SUCCESS) + { + return true; + } + else{ + log_printf(LOG_ERROR, "Error writing registry value: %s", w32_error(err)); + } + } + + return false; +} + void load_dll(unsigned int dllnum) { char path[512]; diff --git a/src/common.h b/src/common.h index 8b14389..81412bf 100644 --- a/src/common.h +++ b/src/common.h @@ -42,7 +42,10 @@ HKEY reg_open_subkey(HKEY parent, const char *path, bool readwrite); void reg_close(HKEY key); bool reg_get_bin(HKEY key, const char *name, void *buf, size_t size, const void *default_value); +bool reg_set_bin(HKEY key, const char *name, void *buf, size_t size); + DWORD reg_get_dword(HKEY key, const char *name, DWORD default_value); +bool reg_set_dword(HKEY key, const char *name, DWORD value); void load_dll(unsigned int dllnum); void unload_dlls(void); diff --git a/src/config.c b/src/config.c index b4e149a..1c5de81 100644 --- a/src/config.c +++ b/src/config.c @@ -37,6 +37,25 @@ main_config_t get_main_config(void) HKEY reg = reg_open_main(false); DWORD version = reg_get_dword(reg, "config_version", 1); + config.single_iface = reg_get_dword(reg, "single_iface", true); + 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) { struct v1_global_config reg_config; @@ -48,6 +67,8 @@ main_config_t get_main_config(void) config.bcast_all = reg_config.bcast_all; config.src_filter = reg_config.filter; } + + config.router_port = reg_get_dword(reg, "control_port", config.router_port); } else if(version == 2) { diff --git a/src/config.h b/src/config.h index 6fc0f51..2b04a2e 100644 --- a/src/config.h +++ b/src/config.h @@ -33,6 +33,10 @@ typedef struct main_config { unsigned int addr_cache_ttl; unsigned int iface_ttl; + + bool single_iface; + addr32_t single_netnum; + addr48_t single_nodenum; } main_config_t; struct v1_global_config {