1
0
mirror of https://github.com/solemnwarning/ipxwrapper synced 2024-12-30 16:45:37 +01:00

Host list entries are now identified by both network AND node numbers and expire after TTL (60) seconds of not receiving any packets.

This commit is contained in:
Daniel Collins 2011-04-23 23:42:14 +00:00
parent 983265ffc0
commit 4afad85e3c
3 changed files with 41 additions and 17 deletions

View File

@ -24,6 +24,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdint.h> #include <stdint.h>
#include <time.h>
#include "ipxwrapper.h" #include "ipxwrapper.h"
@ -51,7 +52,7 @@ static HKEY regkey = NULL;
static HMODULE load_sysdll(char const *name); static HMODULE load_sysdll(char const *name);
static int init_router(void); static int init_router(void);
static DWORD WINAPI router_main(LPVOID argp); static DWORD WINAPI router_main(LPVOID argp);
static void add_host(unsigned char *hwaddr, uint32_t ipaddr); static void add_host(const unsigned char *net, const unsigned char *node, uint32_t ipaddr);
BOOL WINAPI DllMain(HINSTANCE me, DWORD why, LPVOID res) { BOOL WINAPI DllMain(HINSTANCE me, DWORD why, LPVOID res) {
if(why == DLL_PROCESS_ATTACH) { if(why == DLL_PROCESS_ATTACH) {
@ -307,17 +308,17 @@ static HMODULE load_sysdll(char const *name) {
static int init_router(void) { static int init_router(void) {
net_fd = socket(AF_INET, SOCK_DGRAM, 0); net_fd = socket(AF_INET, SOCK_DGRAM, 0);
if(net_fd == -1) { if(net_fd == -1) {
debug("Failed to create listener socket: %s", w32_error(WSAGetLastError())); debug("Failed to create network socket: %s", w32_error(WSAGetLastError()));
return 0; return 0;
} }
struct sockaddr_in bind_addr; struct sockaddr_in bind_addr;
bind_addr.sin_family = AF_INET; bind_addr.sin_family = AF_INET;
bind_addr.sin_addr.s_addr = inet_addr("0.0.0.0"); bind_addr.sin_addr.s_addr = INADDR_ANY;
bind_addr.sin_port = htons(PORT); bind_addr.sin_port = htons(PORT);
if(bind(net_fd, (struct sockaddr*)&bind_addr, sizeof(bind_addr)) == -1) { if(bind(net_fd, (struct sockaddr*)&bind_addr, sizeof(bind_addr)) == -1) {
debug("Failed to bind listener socket"); debug("Failed to bind network socket: %s", w32_error(WSAGetLastError()));
return 0; return 0;
} }
@ -381,7 +382,7 @@ static DWORD WINAPI router_main(LPVOID buf) {
lock_mutex(); lock_mutex();
add_host(packet->src_node, ntohl(addr.sin_addr.s_addr)); add_host(packet->src_net, packet->src_node, ntohl(addr.sin_addr.s_addr));
for(sockptr = sockets; sockptr; sockptr = sockptr->next) { for(sockptr = sockets; sockptr; sockptr = sockptr->next) {
if( if(
@ -432,13 +433,15 @@ char const *w32_error(DWORD errnum) {
return buf; return buf;
} }
/* Add a host to the hosts list */ /* Add a host to the hosts list or update an existing one */
static void add_host(unsigned char *hwaddr, uint32_t ipaddr) { static void add_host(const unsigned char *net, const unsigned char *node, uint32_t ipaddr) {
ipx_host *hptr = hosts; ipx_host *hptr = hosts;
while(hptr) { while(hptr) {
if(memcmp(hptr->hwaddr, hwaddr, 6) == 0) { if(memcmp(hptr->ipx_net, net, 4) == 0 && memcmp(hptr->ipx_node, node, 6) == 0) {
hptr->ipaddr = ipaddr; hptr->ipaddr = ipaddr;
hptr->last_packet = time(NULL);
return; return;
} }
@ -451,24 +454,40 @@ static void add_host(unsigned char *hwaddr, uint32_t ipaddr) {
return; return;
} }
INIT_HOST(hptr); memcpy(hptr->ipx_net, net, 4);
memcpy(hptr->ipx_node, node, 6);
memcpy(hptr->hwaddr, hwaddr, 6);
hptr->ipaddr = ipaddr; hptr->ipaddr = ipaddr;
hptr->last_packet = time(NULL);
hptr->next = hosts; hptr->next = hosts;
hosts = hptr; hosts = hptr;
} }
/* Search the hosts list */ /* Search the hosts list */
ipx_host *find_host(unsigned char *hwaddr) { ipx_host *find_host(const unsigned char *net, const unsigned char *node) {
ipx_host *hptr = hosts; ipx_host *hptr = hosts, *pptr = NULL;
while(hptr) { while(hptr) {
if(memcmp(hptr->hwaddr, hwaddr, 6) == 0) { if(memcmp(hptr->ipx_net, net, 4) == 0 && memcmp(hptr->ipx_node, node, 6) == 0) {
return hptr; if(hptr->last_packet+TTL < time(NULL)) {
/* Host record has expired, delete */
if(pptr) {
pptr->next = hptr->next;
free(hptr);
}else{
hosts = hptr->next;
free(hptr);
}
return NULL;
}else{
return hptr;
}
} }
pptr = hptr;
hptr = hptr->next; hptr = hptr->next;
} }

View File

@ -23,6 +23,8 @@
#include <stdint.h> #include <stdint.h>
#define PORT 54792 #define PORT 54792
#define TTL 60
#define DEBUG "ipxwrapper.log" #define DEBUG "ipxwrapper.log"
/* Maximum UDP data size is 65467, we use a smaller value to ensure we have /* Maximum UDP data size is 65467, we use a smaller value to ensure we have
@ -126,8 +128,11 @@ struct ipx_nic {
}; };
struct ipx_host { struct ipx_host {
unsigned char hwaddr[6]; unsigned char ipx_net[4];
unsigned char ipx_node[6];
uint32_t ipaddr; uint32_t ipaddr;
time_t last_packet;
ipx_host *next; ipx_host *next;
}; };
@ -156,7 +161,7 @@ void lock_mutex(void);
void unlock_mutex(void); void unlock_mutex(void);
IP_ADAPTER_INFO *get_nics(void); IP_ADAPTER_INFO *get_nics(void);
char const *w32_error(DWORD errnum); char const *w32_error(DWORD errnum);
ipx_host *find_host(unsigned char *hwaddr); ipx_host *find_host(const unsigned char *net, const unsigned char *node);
INT APIENTRY r_EnumProtocolsA(LPINT,LPVOID,LPDWORD); INT APIENTRY r_EnumProtocolsA(LPINT,LPVOID,LPDWORD);
INT APIENTRY r_EnumProtocolsW(LPINT,LPVOID,LPDWORD); INT APIENTRY r_EnumProtocolsW(LPINT,LPVOID,LPDWORD);

View File

@ -611,7 +611,7 @@ int WSAAPI sendto(SOCKET fd, const char *buf, int len, int flags, const struct s
lock_mutex(); lock_mutex();
ipx_host *hptr = find_host(packet->dest_node); ipx_host *hptr = find_host(packet->dest_net, packet->dest_node);
for(nic = nics; nic; nic = nic->next) { for(nic = nics; nic; nic = nic->next) {
if(( if((