From d046b6522df18e1424540092e9e36b6e21d9fd46 Mon Sep 17 00:00:00 2001 From: Daniel Collins Date: Wed, 7 Sep 2011 20:03:16 +0000 Subject: [PATCH] Switchover to new router code --- Makefile | 4 +- src/ipxwrapper.c | 174 ++++++-------------------------- src/ipxwrapper.h | 6 +- src/ipxwrapper_stubs.txt | 4 + src/router.c | 44 +++++--- src/router.h | 6 +- src/winsock.c | 211 ++++++++++----------------------------- 7 files changed, 126 insertions(+), 323 deletions(-) diff --git a/Makefile b/Makefile index f447733..964185c 100644 --- a/Makefile +++ b/Makefile @@ -18,14 +18,14 @@ CFLAGS := -Wall -I./include/ CXXFLAGS := -Wall -I./include/ IPXWRAPPER_DEPS := src/ipxwrapper.o src/winsock.o src/ipxwrapper_stubs.o src/log.o src/common.o \ - src/interface.o src/ipxwrapper.def + src/interface.o src/router.o src/ipxwrapper.def BIN_FILES := changes.txt license.txt readme.txt ipxwrapper.dll mswsock.dll wsock32.dll ipxconfig.exe SRC_FILES := changes.txt license.txt Makefile mkstubs.pl readme.txt src/config.h src/ipxconfig.cpp \ src/ipxwrapper.c src/ipxwrapper.def src/ipxwrapper.h src/ipxwrapper_stubs.txt src/log.c \ src/mswsock.def src/mswsock_stubs.txt src/stubdll.c src/winsock.c src/winstuff.h src/wsock32.def \ src/wsock32_stubs.txt src/directplay.c src/dpwsockx.def src/dpwsockx_stubs.txt src/common.c \ - src/common.h include/dplay.h include/dplaysp.h include/dplobby.h + src/common.h src/router.c src/router.h include/dplay.h include/dplaysp.h include/dplobby.h all: ipxwrapper.dll wsock32.dll mswsock.dll ipxconfig.exe dpwsockx.dll diff --git a/src/ipxwrapper.c b/src/ipxwrapper.c index 2d36132..db7e9c8 100644 --- a/src/ipxwrapper.c +++ b/src/ipxwrapper.c @@ -29,6 +29,7 @@ #include "ipxwrapper.h" #include "common.h" #include "interface.h" +#include "router.h" #define DLL_UNLOAD(dll) \ if(dll) {\ @@ -41,7 +42,6 @@ struct ipx_interface *nics = NULL; ipx_host *hosts = NULL; SOCKET net_fd = -1; struct reg_global global_conf; -static void *router_buf = NULL; HMODULE winsock2_dll = NULL; HMODULE mswsock_dll = NULL; @@ -49,10 +49,9 @@ HMODULE wsock32_dll = NULL; static HANDLE mutex = NULL; static HANDLE router_thread = NULL; -static DWORD router_tid = 0; +struct router_vars *router = NULL; -static int init_router(void); -static DWORD WINAPI router_main(LPVOID argp); +static BOOL start_router(void); BOOL WINAPI DllMain(HINSTANCE me, DWORD why, LPVOID res) { if(why == DLL_PROCESS_ATTACH) { @@ -90,21 +89,23 @@ BOOL WINAPI DllMain(HINSTANCE me, DWORD why, LPVOID res) { return FALSE; } - if(!init_router()) { + if(!start_router()) { return FALSE; } }else if(why == DLL_PROCESS_DETACH) { - if(router_thread && GetCurrentThreadId() != router_tid) { - TerminateThread(router_thread, 0); + if(router_thread) { + EnterCriticalSection(&(router->crit_sec)); + + router->running = FALSE; + SetEvent(router->wsa_event); + + LeaveCriticalSection(&(router->crit_sec)); + + WaitForSingleObject(router_thread, INFINITE); router_thread = NULL; - } - - free(router_buf); - router_buf = NULL; - - if(net_fd >= 0) { - closesocket(net_fd); - net_fd = -1; + + router_destroy(router); + router = NULL; } if(mutex) { @@ -182,143 +183,24 @@ void unlock_mutex(void) { } /* Initialize and start the router thread */ -static int init_router(void) { - net_fd = r_socket(AF_INET, SOCK_DGRAM, 0); - if(net_fd == -1) { - log_printf("Failed to create network socket: %s", w32_error(WSAGetLastError())); - return 0; +static BOOL start_router(void) { + if(!(router = router_init(FALSE))) { + return FALSE; } - struct sockaddr_in bind_addr; - bind_addr.sin_family = AF_INET; - bind_addr.sin_addr.s_addr = INADDR_ANY; - bind_addr.sin_port = htons(global_conf.udp_port); - - if(r_bind(net_fd, (struct sockaddr*)&bind_addr, sizeof(bind_addr)) == -1) { - log_printf("Failed to bind network socket: %s", w32_error(WSAGetLastError())); - return 0; - } - - BOOL broadcast = TRUE; - int bufsize = 524288; /* 512KiB */ - - r_setsockopt(net_fd, SOL_SOCKET, SO_BROADCAST, (char*)&broadcast, sizeof(BOOL)); - r_setsockopt(net_fd, SOL_SOCKET, SO_RCVBUF, (char*)&bufsize, sizeof(int)); - r_setsockopt(net_fd, SOL_SOCKET, SO_SNDBUF, (char*)&bufsize, sizeof(int)); - - router_buf = malloc(PACKET_BUF_SIZE); - if(!router_buf) { - log_printf("Not enough memory for router buffer (64KiB)"); - return 0; - } - - router_thread = CreateThread(NULL, 0, &router_main, NULL, 0, &router_tid); + router_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&router_main, router, 0, NULL); if(!router_thread) { - log_printf("Failed to create router thread"); - return 0; + log_printf("Failed to create router thread: %s", w32_error(GetLastError())); + + router_destroy(router); + router = NULL; + + return FALSE; } - return 1; -} - -/* Router thread main function - * - * The router thread recieves packets from the listening port and forwards them - * to the UDP sockets which emulate IPX. -*/ -static DWORD WINAPI router_main(LPVOID notused) { - ipx_packet *packet = router_buf; - int addrlen, rval, sval; - unsigned char f6[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; - struct sockaddr_in addr; - ipx_socket *sockptr; + net_fd = router->udp_sock; - while(1) { - addrlen = sizeof(addr); - rval = r_recvfrom(net_fd, (char*)packet, PACKET_BUF_SIZE, 0, (struct sockaddr*)&addr, &addrlen); - if(rval <= 0) { - log_printf("Error recieving packet: %s", w32_error(WSAGetLastError())); - continue; - } - - if(global_conf.filter) { - struct ipx_interface *nic = nics; - - while(nic) { - if((nic->ipaddr & nic->netmask) == (addr.sin_addr.s_addr & nic->netmask)) { - break; - } - - nic = nic->next; - } - - if(!nic) { - /* Packet not recieved from subnet of an enabled interface */ - continue; - } - } - - packet->size = ntohs(packet->size); - - if(packet->size > MAX_PACKET_SIZE || packet->size+sizeof(ipx_packet)-1 != rval) { - log_printf("Recieved packet with incorrect size field, discarding"); - continue; - } - - lock_mutex(); - - add_host(packet->src_net, packet->src_node, addr.sin_addr.s_addr); - - for(sockptr = sockets; sockptr; sockptr = sockptr->next) { - if( - sockptr->flags & IPX_RECV && - ( - !(sockptr->flags & IPX_FILTER) || - packet->ptype == sockptr->f_ptype - ) && (( - sockptr->flags & IPX_BOUND && - packet->dest_socket == sockptr->socket && - ( - memcmp(packet->dest_net, sockptr->nic->ipx_net, 4) == 0 || - ( - memcmp(packet->dest_net, f6, 4) == 0 && - (!global_conf.w95_bug || sockptr->flags & IPX_BROADCAST) - ) - ) && ( - memcmp(packet->dest_node, sockptr->nic->ipx_node, 6) == 0 || - ( - memcmp(packet->dest_node, f6, 6) == 0 && - (!global_conf.w95_bug || sockptr->flags & IPX_BROADCAST) - ) - ) - ) || ( - sockptr->flags & IPX_EX_BOUND && - packet->dest_socket == sockptr->ex_socket && - ( - memcmp(packet->dest_net, sockptr->ex_nic->ipx_net, 4) == 0 || - memcmp(packet->dest_net, f6, 4) == 0 - ) && ( - memcmp(packet->dest_node, sockptr->ex_nic->ipx_node, 6) == 0 || - memcmp(packet->dest_node, f6, 6) == 0 - ) - )) - ) { - addrlen = sizeof(addr); - if(r_getsockname(sockptr->fd, (struct sockaddr*)&addr, &addrlen) == -1) { - continue; - } - - sval = r_sendto(sockptr->fd, (char*)packet, rval, 0, (struct sockaddr*)&addr, addrlen); - if(sval == -1) { - log_printf("Error relaying packet: %s", w32_error(WSAGetLastError())); - } - } - } - - unlock_mutex(); - } - - return 0; + return TRUE; } /* Add a host to the hosts list or update an existing one */ diff --git a/src/ipxwrapper.h b/src/ipxwrapper.h index 9abb471..ecb675d 100644 --- a/src/ipxwrapper.h +++ b/src/ipxwrapper.h @@ -25,6 +25,7 @@ #include #include "config.h" +#include "router.h" /* Maximum UDP data size is 65467, we use a smaller value to ensure we have * plenty of space to play with for headers, etc @@ -65,8 +66,8 @@ struct ipx_socket { uint8_t f_ptype; /* Undefined when IPX_FILTER isn't set */ /* The following values are undefined when IPX_BOUND is not set */ - struct ipx_interface *nic; - uint16_t socket; /* Stored in NETWORK BYTE ORDER */ + struct sockaddr_ipx addr; + uint32_t nic_bcast; /* Extra bind address, only used for receiving packets. * Only defined when IPX_EX_BOUND is set. @@ -107,6 +108,7 @@ extern struct ipx_interface *nics; extern ipx_host *hosts; extern SOCKET net_fd; extern struct reg_global global_conf; +extern struct router_vars *router; extern HMODULE winsock2_dll; extern HMODULE mswsock_dll; diff --git a/src/ipxwrapper_stubs.txt b/src/ipxwrapper_stubs.txt index cab1044..d5e2a6b 100644 --- a/src/ipxwrapper_stubs.txt +++ b/src/ipxwrapper_stubs.txt @@ -8,6 +8,10 @@ ntohl htons ntohs select +WSACreateEvent +WSAEventSelect +WSACloseEvent +WSAResetEvent r_EnumProtocolsA r_EnumProtocolsW r_WSARecvEx diff --git a/src/router.c b/src/router.c index 1b03f1d..6b2c737 100644 --- a/src/router.c +++ b/src/router.c @@ -72,8 +72,8 @@ struct router_vars *router_init(BOOL global) { struct sockaddr_in addr; addr.sin_family = AF_INET; - addr.sin_addr.s_addr = inet_addr("127.0.0.1"); - addr.sin_port = 9999; + addr.sin_addr.s_addr = INADDR_ANY; + addr.sin_port = htons(global_conf.udp_port); if(bind(router->udp_sock, (struct sockaddr*)&addr, sizeof(addr)) == -1) { log_printf("Error binding UDP socket: %s", w32_error(WSAGetLastError())); @@ -143,24 +143,28 @@ void router_destroy(struct router_vars *router) { DWORD router_main(void *arg) { struct router_vars *router = arg; + const unsigned char f6[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; + while(1) { WaitForSingleObject(router->wsa_event, INFINITE); EnterCriticalSection(&(router->crit_sec)); + WSAResetEvent(router->wsa_event); + if(!router->running) { LeaveCriticalSection(&(router->crit_sec)); return 0; } + LeaveCriticalSection(&(router->crit_sec)); + struct sockaddr_in addr; int addrlen = sizeof(addr); - int len = recvfrom(router->udp_sock, router->recvbuf, PACKET_BUF_SIZE, 0, (struct sockaddr*)&addr, &addrlen); + int len = r_recvfrom(router->udp_sock, router->recvbuf, PACKET_BUF_SIZE, 0, (struct sockaddr*)&addr, &addrlen); if(len == -1) { - LeaveCriticalSection(&(router->crit_sec)); - - if(WSAGetLastError() == WSAEWOULDBLOCK) { + if(WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAECONNRESET) { continue; } @@ -168,6 +172,8 @@ DWORD router_main(void *arg) { return 1; } + EnterCriticalSection(&(router->crit_sec)); + ipx_packet *packet = (ipx_packet*)router->recvbuf; /* Check that the packet arrived from the subnet of an enabled network @@ -186,6 +192,7 @@ DWORD router_main(void *arg) { } if(!iface) { + LeaveCriticalSection(&(router->crit_sec)); continue; } } @@ -193,7 +200,7 @@ DWORD router_main(void *arg) { packet->size = ntohs(packet->size); if(packet->size > MAX_PACKET_SIZE || packet->size + sizeof(ipx_packet) - 1 != len) { - log_printf("Recieved packet with incorrect size field, discarding"); + LeaveCriticalSection(&(router->crit_sec)); continue; } @@ -202,8 +209,6 @@ DWORD router_main(void *arg) { struct router_addr *ra = router->addrs; while(ra) { - unsigned char f6[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; - if( ra->local_port && (ra->filter_ptype < 0 || ra->filter_ptype == packet->ptype) && @@ -214,7 +219,7 @@ DWORD router_main(void *arg) { addr.sin_addr.s_addr = inet_addr("127.0.0.1"); addr.sin_port = ra->local_port; - if(sendto(router->udp_sock, (char*)packet, len, 0, (struct sockaddr*)&addr, sizeof(addr)) == -1) { + if(r_sendto(router->udp_sock, (char*)packet, len, 0, (struct sockaddr*)&addr, sizeof(addr)) == -1) { log_printf("Error relaying packet: %s", w32_error(WSAGetLastError())); } } @@ -228,7 +233,20 @@ DWORD router_main(void *arg) { return 0; } -int router_bind(struct router_vars *router, SOCKET control, SOCKET sock, struct sockaddr_ipx *addr) { +int router_bind(struct router_vars *router, SOCKET control, SOCKET sock, struct sockaddr_ipx *addr, uint32_t *nic_bcast) { + /* Network number 00:00:00:00 is specified as the "current" network, this code + * treats it as a wildcard when used for the network OR node numbers. + * + * According to MSDN 6, IPX socket numbers are unique to systems rather than + * interfaces and as such, the same socket number cannot be bound to more than + * one interface, my code lacks any "catch all" address like INADDR_ANY as I have + * not found any mentions of an equivalent address for IPX. This means that a + * given socket number may only be used on one interface. + * + * If you know the above information about IPX socket numbers to be incorrect, + * PLEASE email me with corrections! + */ + struct ipx_interface *ifaces = get_interfaces(-1), *iface; unsigned char z6[] = {0,0,0,0,0,0}; @@ -253,6 +271,8 @@ int router_bind(struct router_vars *router, SOCKET control, SOCKET sock, struct memcpy(addr->sa_netnum, iface->ipx_net, 4); memcpy(addr->sa_nodenum, iface->ipx_node, 6); + *nic_bcast = iface->bcast; + free_interfaces(ifaces); EnterCriticalSection(&(router->crit_sec)); @@ -352,7 +372,7 @@ void router_set_port(struct router_vars *router, SOCKET control, SOCKET sock, ui LeaveCriticalSection(&(router->crit_sec)); } -void router_close(struct router_vars *router, SOCKET control, SOCKET sock) { +void router_unbind(struct router_vars *router, SOCKET control, SOCKET sock) { EnterCriticalSection(&(router->crit_sec)); struct router_addr *addr = router->addrs, *prev = NULL; diff --git a/src/router.h b/src/router.h index b1f1f53..3d8c939 100644 --- a/src/router.h +++ b/src/router.h @@ -61,9 +61,11 @@ struct router_vars { struct router_vars *router_init(BOOL global); void router_destroy(struct router_vars *router); -int router_bind(struct router_vars *router, SOCKET control, SOCKET sock, struct sockaddr_ipx *addr); +DWORD router_main(void *arg); + +int router_bind(struct router_vars *router, SOCKET control, SOCKET sock, struct sockaddr_ipx *addr, uint32_t *nic_bcast); void router_set_port(struct router_vars *router, SOCKET control, SOCKET sock, uint16_t port); -void router_close(struct router_vars *router, SOCKET control, SOCKET sock); +void router_unbind(struct router_vars *router, SOCKET control, SOCKET sock); void router_set_filter(struct router_vars *router, SOCKET control, SOCKET sock, int ptype); #endif /* !IPXWRAPPER_ROUTER_H */ diff --git a/src/winsock.c b/src/winsock.c index e51d6c4..5d7bd50 100644 --- a/src/winsock.c +++ b/src/winsock.c @@ -26,6 +26,7 @@ #include "ipxwrapper.h" #include "common.h" #include "interface.h" +#include "router.h" INT APIENTRY EnumProtocolsA(LPINT protocols, LPVOID buf, LPDWORD bsptr) { int bufsize = *bsptr, rval, i, want_ipx = 0; @@ -180,6 +181,8 @@ int WSAAPI closesocket(SOCKET fd) { log_printf("IPX socket closed (fd = %d)", fd); + router_unbind(router, 0, fd); + if(ptr == sockets) { sockets = ptr->next; free(ptr); @@ -201,122 +204,61 @@ int WSAAPI bind(SOCKET fd, const struct sockaddr *addr, int addrlen) { ipx_socket *ptr = get_socket(fd); if(ptr) { - struct sockaddr_ipx *ipxaddr = (struct sockaddr_ipx*)addr; + struct sockaddr_ipx ipxaddr; char net_s[12], node_s[18]; - NET_TO_STRING(net_s, ipxaddr->sa_netnum); - NODE_TO_STRING(node_s, ipxaddr->sa_nodenum); + if(addrlen < sizeof(ipxaddr)) { + RETURN_WSA(WSAEFAULT, -1); + } - log_printf("bind(%d, net=%s node=%s socket=%hu)", fd, net_s, node_s, ntohs(ipxaddr->sa_socket)); + memcpy(&ipxaddr, addr, sizeof(ipxaddr)); + + NET_TO_STRING(net_s, ipxaddr.sa_netnum); + NODE_TO_STRING(node_s, ipxaddr.sa_nodenum); + + log_printf("bind(%d, net=%s node=%s socket=%hu)", fd, net_s, node_s, ntohs(ipxaddr.sa_socket)); if(ptr->flags & IPX_BOUND) { log_printf("bind failed: socket already bound"); RETURN_WSA(WSAEINVAL, -1); } - /* Network number 00:00:00:00 is specified as the "current" network, this code - * treats it as a wildcard when used for the network OR node numbers. - * - * According to MSDN 6, IPX socket numbers are unique to systems rather than - * interfaces and as such, the same socket number cannot be bound to more than - * one interface, my code lacks any "catch all" address like INADDR_ANY as I have - * not found any mentions of an equivalent address for IPX. This means that a - * given socket number may only be used on one interface. - * - * If you know the above information about IPX socket numbers to be incorrect, - * PLEASE email me with corrections! - */ - - unsigned char z6[] = {0,0,0,0,0,0}; - struct ipx_interface *nic = nics; - - while(nic) { - if( - (memcmp(ipxaddr->sa_netnum, nic->ipx_net, 4) == 0 || memcmp(ipxaddr->sa_netnum, z6, 4) == 0) && - (memcmp(ipxaddr->sa_nodenum, nic->ipx_node, 6) == 0 || memcmp(ipxaddr->sa_nodenum, z6, 6) == 0) - ) { - break; - } - - nic = nic->next; + if(router_bind(router, 0, fd, &ipxaddr, &(ptr->nic_bcast)) == -1) { + RETURN(-1); } - if(!nic) { - log_printf("bind failed: no such address"); - RETURN_WSA(WSAEADDRNOTAVAIL, -1); - } + NET_TO_STRING(net_s, ipxaddr.sa_netnum); + NODE_TO_STRING(node_s, ipxaddr.sa_nodenum); - ptr->nic = nic; - - if(ipxaddr->sa_socket == 0) { - /* Automatic socket allocations start at 1024, I have no idea if - * this is normal IPX behaviour, but IP does it and it doesn't seem - * to interfere with any IPX software I've tested. - */ - - uint16_t s = 1024; - ipx_socket *socket = sockets; - - while(socket) { - if(ntohs(socket->socket) == s && socket->flags & IPX_BOUND) { - if(s == 65535) { - log_printf("bind failed: out of sockets?!"); - RETURN_WSA(WSAEADDRNOTAVAIL, -1); - } - - s++; - socket = sockets; - - continue; - } - - socket = socket->next; - } - - ptr->socket = htons(s); - }else{ - /* Test if any bound socket is using the requested socket number. */ - - ipx_socket *socket = sockets; - - while(socket) { - if(socket->socket == ipxaddr->sa_socket && socket->flags & IPX_BOUND) { - log_printf("bind failed: requested socket in use"); - RETURN_WSA(WSAEADDRINUSE, -1); - } - - socket = socket->next; - } - - ptr->socket = ipxaddr->sa_socket; - } - - NET_TO_STRING(net_s, nic->ipx_net); - NODE_TO_STRING(node_s, nic->ipx_node); - - log_printf("bind address: net=%s node=%s socket=%hu", net_s, node_s, ntohs(ptr->socket)); - - /* TODO: Bind fake socket in socket() call rather than here? - * - * I think I put the bind() call for it here so that the fd given to the - * program would be in the expected un-bound state, although I'm not sure - * if there are any winsock calls it could ONLY make on such a socket. - */ + log_printf("bind address: net=%s node=%s socket=%hu", net_s, node_s, ntohs(ipxaddr.sa_socket)); struct sockaddr_in bind_addr; bind_addr.sin_family = AF_INET; - bind_addr.sin_port = 0; bind_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); + bind_addr.sin_port = 0; - int rval = r_bind(fd, (struct sockaddr*)&bind_addr, sizeof(bind_addr)); - - if(rval == 0) { - ptr->flags |= IPX_BOUND; - }else{ - log_printf("Binding fake socket failed: %s", w32_error(WSAGetLastError())); + if(r_bind(fd, (struct sockaddr*)&bind_addr, sizeof(bind_addr)) == -1) { + log_printf("Binding local UDP socket failed: %s", w32_error(WSAGetLastError())); + + router_unbind(router, 0, fd); + RETURN(-1); } - RETURN(rval); + int al = sizeof(bind_addr); + + if(r_getsockname(fd, (struct sockaddr*)&bind_addr, &al) == -1) { + log_printf("getsockname failed: %s", w32_error(WSAGetLastError())); + + router_unbind(router, 0, fd); + RETURN(-1); + } + + memcpy(&(ptr->addr), &ipxaddr, sizeof(ipxaddr)); + ptr->flags |= IPX_BOUND; + + router_set_port(router, 0, fd, bind_addr.sin_port); + + RETURN(0); }else{ RETURN(r_bind(fd, addr, addrlen)); } @@ -326,61 +268,10 @@ int WSAAPI bind(SOCKET fd, const struct sockaddr *addr, int addrlen) { * Attempts to bind socket 0 will really bind socket 0 */ int ipx_ex_bind(SOCKET fd, const struct sockaddr_ipx *ipxaddr) { - ipx_socket *ptr = get_socket(fd); - - if(!ipxaddr) { - /* Call with NULL address to remove extra bind */ - log_printf("ipx_ex_bind(%d, NULL)", fd); - - ptr->flags &= ~IPX_EX_BOUND; - RETURN(0); - } - - char net_s[12], node_s[18]; - - NET_TO_STRING(net_s, ipxaddr->sa_netnum); - NODE_TO_STRING(node_s, ipxaddr->sa_nodenum); - - log_printf("ipx_ex_bind(%d, net=%s node=%s socket=%hu)", fd, net_s, node_s, ntohs(ipxaddr->sa_socket)); - - if(!(ptr->flags & IPX_BOUND)) { - log_printf("ipx_ex_bind: Socket is not bound"); - RETURN_WSA(WSAEINVAL, -1); - } - - unsigned char z6[] = {0,0,0,0,0,0}; - struct ipx_interface *nic = nics; - - while(nic) { - if( - (memcmp(ipxaddr->sa_netnum, nic->ipx_net, 4) == 0 || memcmp(ipxaddr->sa_netnum, z6, 4) == 0) && - (memcmp(ipxaddr->sa_nodenum, nic->ipx_node, 6) == 0 || memcmp(ipxaddr->sa_nodenum, z6, 6) == 0) - ) { - break; - } - - nic = nic->next; - } - - if(!nic) { - log_printf("ipx_ex_bind: no such address"); - RETURN_WSA(WSAEADDRNOTAVAIL, -1); - } - - NET_TO_STRING(net_s, nic->ipx_net); - NODE_TO_STRING(node_s, nic->ipx_node); - - log_printf("bind address: net=%s node=%s socket=%hu", net_s, node_s, ntohs(ipxaddr->sa_socket)); - - ptr->ex_nic = nic; - ptr->ex_socket = ipxaddr->sa_socket; - ptr->flags |= IPX_EX_BOUND; - - RETURN(0); + return 0; } int WSAAPI getsockname(SOCKET fd, struct sockaddr *addr, int *addrlen) { - struct sockaddr_ipx *ipxaddr = (struct sockaddr_ipx*)addr; ipx_socket *ptr = get_socket(fd); if(ptr) { @@ -390,11 +281,7 @@ int WSAAPI getsockname(SOCKET fd, struct sockaddr *addr, int *addrlen) { RETURN_WSA(WSAEFAULT, -1); } - ipxaddr->sa_family = AF_IPX; - memcpy(ipxaddr->sa_netnum, ptr->nic->ipx_net, 4); - memcpy(ipxaddr->sa_nodenum, ptr->nic->ipx_node, 6); - ipxaddr->sa_socket = ptr->socket; - + memcpy(addr, &(ptr->addr), sizeof(ptr->addr)); *addrlen = sizeof(struct sockaddr_ipx); RETURN(0); @@ -629,11 +516,16 @@ int WSAAPI setsockopt(SOCKET fd, int level, int optname, const char FAR *optval, sockptr->f_ptype = *intval; sockptr->flags |= IPX_FILTER; + router_set_filter(router, 0, fd, *intval); + RETURN(0); } if(optname == IPX_STOPFILTERPTYPE) { sockptr->flags &= ~IPX_FILTER; + + router_set_filter(router, 0, fd, -1); + RETURN(0); } @@ -705,12 +597,12 @@ int WSAAPI sendto(SOCKET fd, const char *buf, int len, int flags, const struct s unsigned char z6[] = {0,0,0,0,0,0}; if(memcmp(packet->dest_net, z6, 4) == 0) { - memcpy(packet->dest_net, sockptr->nic->ipx_net, 4); + memcpy(packet->dest_net, sockptr->addr.sa_netnum, 4); } - memcpy(packet->src_net, sockptr->nic->ipx_net, 4); - memcpy(packet->src_node, sockptr->nic->ipx_node, 6); - packet->src_socket = sockptr->socket; + memcpy(packet->src_net, sockptr->addr.sa_netnum, 4); + memcpy(packet->src_node, sockptr->addr.sa_nodenum, 6); + packet->src_socket = sockptr->addr.sa_socket; packet->size = htons(len); memcpy(packet->data, buf, len); @@ -720,7 +612,7 @@ int WSAAPI sendto(SOCKET fd, const char *buf, int len, int flags, const struct s struct sockaddr_in saddr; saddr.sin_family = AF_INET; saddr.sin_port = htons(global_conf.udp_port); - saddr.sin_addr.s_addr = (host ? host->ipaddr : (global_conf.bcast_all ? INADDR_BROADCAST : sockptr->nic->bcast)); + saddr.sin_addr.s_addr = (host ? host->ipaddr : (global_conf.bcast_all ? INADDR_BROADCAST : sockptr->nic_bcast)); int sval = r_sendto(net_fd, (char*)packet, psize, 0, (struct sockaddr*)&saddr, sizeof(saddr)); if(sval == -1) { @@ -744,6 +636,7 @@ int PASCAL shutdown(SOCKET fd, int cmd) { if(cmd == SD_RECEIVE || cmd == SD_BOTH) { sockptr->flags &= ~IPX_RECV; + router_set_port(router, 0, fd, 0); } RETURN(0);