From 3d72ad087dfb03b508693e9102f902a286fabed8 Mon Sep 17 00:00:00 2001 From: Daniel Collins Date: Sun, 24 Apr 2011 21:55:57 +0000 Subject: [PATCH] Send broadcasts only to the bound subnet unless option is set in registry, then use INADDR_BROADCAST. Store subnet mask in ipx_nic in load_nics(). --- src/ipxwrapper.c | 8 +++++--- src/ipxwrapper.h | 6 +++--- src/winsock.c | 44 ++++++++++++-------------------------------- 3 files changed, 20 insertions(+), 38 deletions(-) diff --git a/src/ipxwrapper.c b/src/ipxwrapper.c index fec3024..aff2ebc 100644 --- a/src/ipxwrapper.c +++ b/src/ipxwrapper.c @@ -88,6 +88,7 @@ BOOL WINAPI DllMain(HINSTANCE me, DWORD why, LPVOID res) { if(!regkey || RegQueryValueEx(regkey, "global", NULL, NULL, (BYTE*)&global_conf, &gsize) != ERROR_SUCCESS || gsize != sizeof(global_conf)) { global_conf.udp_port = DEFAULT_PORT; global_conf.w95_bug = 1; + global_conf.bcast_all = 0; } if(!load_nics()) { @@ -333,13 +334,13 @@ static DWORD WINAPI router_main(LPVOID buf) { !(sockptr->flags & IPX_FILTER) || packet->ptype == sockptr->f_ptype ) && ( - memcmp(packet->dest_net, sockptr->netnum, 4) == 0 || + 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->nodenum, 6) == 0 || + 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) @@ -471,7 +472,8 @@ static BOOL load_nics(void) { } nnic->ipaddr = inet_addr(ifptr->IpAddressList.IpAddress.String); - nnic->bcast = nnic->ipaddr | ~inet_addr(ifptr->IpAddressList.IpMask.String); + nnic->netmask = inet_addr(ifptr->IpAddressList.IpMask.String); + nnic->bcast = nnic->ipaddr | ~nnic->netmask; memcpy(nnic->hwaddr, ifptr->Address, 6); diff --git a/src/ipxwrapper.h b/src/ipxwrapper.h index cb07848..0d11300 100644 --- a/src/ipxwrapper.h +++ b/src/ipxwrapper.h @@ -87,8 +87,7 @@ 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 */ - unsigned char netnum[4]; - unsigned char nodenum[6]; + ipx_nic *nic; uint16_t socket; /* Stored in NETWORK BYTE ORDER */ ipx_socket *next; @@ -110,8 +109,8 @@ struct ipx_packet { } __attribute__((__packed__)); struct ipx_nic { - /* TODO: Remove if not needed for per-interface sockets in the future */ uint32_t ipaddr; + uint32_t netmask; uint32_t bcast; unsigned char hwaddr[6]; @@ -143,6 +142,7 @@ struct reg_value { struct reg_global { uint16_t udp_port; unsigned char w95_bug; + unsigned char bcast_all; } __attribute__((__packed__)); extern ipx_socket *sockets; diff --git a/src/winsock.c b/src/winsock.c index 7b8d64d..cdbe287 100644 --- a/src/winsock.c +++ b/src/winsock.c @@ -277,8 +277,7 @@ int WSAAPI bind(SOCKET fd, const struct sockaddr *addr, int addrlen) { RETURN_WSA(WSAEADDRNOTAVAIL, -1); } - memcpy(ptr->netnum, nic->ipx_net, 4); - memcpy(ptr->nodenum, nic->ipx_node, 6); + ptr->nic = nic; if(ipxaddr->sa_socket == 0) { /* Automatic socket allocations start at 1024, I have no idea if @@ -366,8 +365,8 @@ int WSAAPI getsockname(SOCKET fd, struct sockaddr *addr, int *addrlen) { } ipxaddr->sa_family = AF_IPX; - memcpy(ipxaddr->sa_netnum, ptr->netnum, 4); - memcpy(ipxaddr->sa_nodenum, ptr->nodenum, 6); + memcpy(ipxaddr->sa_netnum, ptr->nic->ipx_net, 4); + memcpy(ipxaddr->sa_nodenum, ptr->nic->ipx_node, 6); ipxaddr->sa_socket = ptr->socket; *addrlen = sizeof(struct sockaddr_ipx); @@ -649,45 +648,26 @@ 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->netnum, 4); + memcpy(packet->dest_net, sockptr->nic->ipx_net, 4); } - memcpy(packet->src_net, sockptr->netnum, 4); - memcpy(packet->src_node, sockptr->nodenum, 6); + memcpy(packet->src_net, sockptr->nic->ipx_net, 4); + memcpy(packet->src_node, sockptr->nic->ipx_node, 6); packet->src_socket = sockptr->socket; packet->size = htons(len); memcpy(packet->data, buf, len); + ipx_host *host = find_host(packet->dest_net, packet->dest_node); + 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)); - ipx_host *host = find_host(packet->dest_net, packet->dest_node); - - if(host) { - saddr.sin_addr.s_addr = host->ipaddr; - - int sval = r_sendto(net_fd, (char*)packet, psize, 0, (struct sockaddr*)&saddr, sizeof(saddr)); - if(sval == -1) { - len = -1; - } - }else{ - ipx_nic *nic = nics; - int success = 0; - - while(nic) { - saddr.sin_addr.s_addr = nic->bcast; - - int sval = r_sendto(net_fd, (char*)packet, psize, 0, (struct sockaddr*)&saddr, sizeof(saddr)); - if(sval >= 0) { - success = 1; - } - - nic = nic->next; - } - - len = success ? len : -1; + int sval = r_sendto(net_fd, (char*)packet, psize, 0, (struct sockaddr*)&saddr, sizeof(saddr)); + if(sval == -1) { + len = -1; } free(packet);