From 4afad85e3c3bf1b504fdd5893682bbe725438920 Mon Sep 17 00:00:00 2001 From: Daniel Collins Date: Sat, 23 Apr 2011 23:42:14 +0000 Subject: [PATCH] Host list entries are now identified by both network AND node numbers and expire after TTL (60) seconds of not receiving any packets. --- src/ipxwrapper.c | 47 +++++++++++++++++++++++++++++++++-------------- src/ipxwrapper.h | 9 +++++++-- src/winsock.c | 2 +- 3 files changed, 41 insertions(+), 17 deletions(-) diff --git a/src/ipxwrapper.c b/src/ipxwrapper.c index dfe15c0..f90af32 100644 --- a/src/ipxwrapper.c +++ b/src/ipxwrapper.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "ipxwrapper.h" @@ -51,7 +52,7 @@ static HKEY regkey = NULL; static HMODULE load_sysdll(char const *name); static int init_router(void); 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) { if(why == DLL_PROCESS_ATTACH) { @@ -307,17 +308,17 @@ static HMODULE load_sysdll(char const *name) { static int init_router(void) { net_fd = socket(AF_INET, SOCK_DGRAM, 0); 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; } struct sockaddr_in bind_addr; 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); 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; } @@ -381,7 +382,7 @@ static DWORD WINAPI router_main(LPVOID buf) { 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) { if( @@ -432,13 +433,15 @@ char const *w32_error(DWORD errnum) { return buf; } -/* Add a host to the hosts list */ -static void add_host(unsigned char *hwaddr, uint32_t ipaddr) { +/* Add a host to the hosts list or update an existing one */ +static void add_host(const unsigned char *net, const unsigned char *node, uint32_t ipaddr) { ipx_host *hptr = hosts; 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->last_packet = time(NULL); + return; } @@ -451,24 +454,40 @@ static void add_host(unsigned char *hwaddr, uint32_t ipaddr) { 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->last_packet = time(NULL); hptr->next = hosts; hosts = hptr; } /* Search the hosts list */ -ipx_host *find_host(unsigned char *hwaddr) { - ipx_host *hptr = hosts; +ipx_host *find_host(const unsigned char *net, const unsigned char *node) { + ipx_host *hptr = hosts, *pptr = NULL; while(hptr) { - if(memcmp(hptr->hwaddr, hwaddr, 6) == 0) { - return hptr; + if(memcmp(hptr->ipx_net, net, 4) == 0 && memcmp(hptr->ipx_node, node, 6) == 0) { + 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; } diff --git a/src/ipxwrapper.h b/src/ipxwrapper.h index ea24f5c..136a24f 100644 --- a/src/ipxwrapper.h +++ b/src/ipxwrapper.h @@ -23,6 +23,8 @@ #include #define PORT 54792 +#define TTL 60 + #define DEBUG "ipxwrapper.log" /* 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 { - unsigned char hwaddr[6]; + unsigned char ipx_net[4]; + unsigned char ipx_node[6]; + uint32_t ipaddr; + time_t last_packet; ipx_host *next; }; @@ -156,7 +161,7 @@ void lock_mutex(void); void unlock_mutex(void); IP_ADAPTER_INFO *get_nics(void); 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_EnumProtocolsW(LPINT,LPVOID,LPDWORD); diff --git a/src/winsock.c b/src/winsock.c index 46571ac..9822dbf 100644 --- a/src/winsock.c +++ b/src/winsock.c @@ -611,7 +611,7 @@ int WSAAPI sendto(SOCKET fd, const char *buf, int len, int flags, const struct s 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) { if((