mirror of
https://github.com/solemnwarning/ipxwrapper
synced 2024-12-30 16:45:37 +01:00
Perform source address filtering using the IPs registered with the IPX interface
of the target address rather than the one in the router_addr structure. Bugfix: Don't overwrite packet IP address on first relay.
This commit is contained in:
parent
2f9677c3d2
commit
2dd19ce6d7
68
src/router.c
68
src/router.c
@ -289,7 +289,8 @@ DWORD router_main(void *arg) {
|
|||||||
|
|
||||||
struct router_addr *ra = router->addrs;
|
struct router_addr *ra = router->addrs;
|
||||||
|
|
||||||
while(ra) {
|
for(; ra; ra = ra->next)
|
||||||
|
{
|
||||||
if(
|
if(
|
||||||
ra->local_port &&
|
ra->local_port &&
|
||||||
(ra->filter_ptype < 0 || ra->filter_ptype == packet->ptype) &&
|
(ra->filter_ptype < 0 || ra->filter_ptype == packet->ptype) &&
|
||||||
@ -297,23 +298,72 @@ DWORD router_main(void *arg) {
|
|||||||
(memcmp(packet->dest_node, ra->addr.sa_nodenum, 6) == 0 || (memcmp(packet->dest_node, f6, 6) == 0 && (ra->flags & IPX_BROADCAST || !main_config.w95_bug) && ra->flags & IPX_RECV_BCAST)) &&
|
(memcmp(packet->dest_node, ra->addr.sa_nodenum, 6) == 0 || (memcmp(packet->dest_node, f6, 6) == 0 && (ra->flags & IPX_BROADCAST || !main_config.w95_bug) && ra->flags & IPX_RECV_BCAST)) &&
|
||||||
packet->dest_socket == ra->addr.sa_socket &&
|
packet->dest_socket == ra->addr.sa_socket &&
|
||||||
|
|
||||||
/* Check source IP is within correct subnet */
|
|
||||||
((ra->ipaddr & ra->netmask) == (addr.sin_addr.s_addr & ra->netmask) || !main_config.src_filter) &&
|
|
||||||
|
|
||||||
/* Check source address matches remote_addr if set */
|
/* Check source address matches remote_addr if set */
|
||||||
(ra->remote_addr.sa_family == AF_UNSPEC || (memcmp(ra->remote_addr.sa_netnum, packet->src_net, 4) == 0 && memcmp(ra->remote_addr.sa_nodenum, packet->src_node, 6) == 0))
|
(ra->remote_addr.sa_family == AF_UNSPEC || (memcmp(ra->remote_addr.sa_netnum, packet->src_net, 4) == 0 && memcmp(ra->remote_addr.sa_nodenum, packet->src_node, 6) == 0))
|
||||||
) {
|
) {
|
||||||
|
addr32_t ra_net = addr32_in(ra->addr.sa_netnum);
|
||||||
|
addr48_t ra_node = addr48_in(ra->addr.sa_nodenum);
|
||||||
|
|
||||||
|
/* Check source address */
|
||||||
|
|
||||||
|
if(main_config.iface_mode != IFACE_MODE_ALL)
|
||||||
|
{
|
||||||
|
/* Fetch the interface this socket is bound to. */
|
||||||
|
|
||||||
|
ipx_interface_t *iface = ipx_interface_by_addr(ra_net, ra_node);
|
||||||
|
|
||||||
|
if(!iface)
|
||||||
|
{
|
||||||
|
char net_s[ADDR32_STRING_SIZE], node_s[ADDR48_STRING_SIZE];
|
||||||
|
|
||||||
|
addr32_string(net_s, ra_net);
|
||||||
|
addr48_string(node_s, ra_node);
|
||||||
|
|
||||||
|
log_printf(LOG_WARNING, "No iface for %s/%s! Stale bind?", net_s, node_s);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Iterate over the subnets and compare
|
||||||
|
* to the packet source address.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ipx_interface_ip_t *ip;
|
||||||
|
|
||||||
|
int source_ok = 0;
|
||||||
|
|
||||||
|
DL_FOREACH(iface->ipaddr, ip)
|
||||||
|
{
|
||||||
|
if((ip->ipaddr & ip->netmask) == (addr.sin_addr.s_addr & ip->netmask))
|
||||||
|
{
|
||||||
|
source_ok = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free_ipx_interface(iface);
|
||||||
|
|
||||||
|
if(!source_ok)
|
||||||
|
{
|
||||||
|
/* Source matching failed. */
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
log_printf(LOG_DEBUG, "Relaying packet to local port %hu", ntohs(ra->local_port));
|
log_printf(LOG_DEBUG, "Relaying packet to local port %hu", ntohs(ra->local_port));
|
||||||
|
|
||||||
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
struct sockaddr_in send_addr;
|
||||||
addr.sin_port = ra->local_port;
|
|
||||||
|
|
||||||
if(sendto(router->udp_sock, (char*)rp_header, sizeof(*rp_header) + len, 0, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
|
send_addr.sin_family = AF_INET;
|
||||||
|
send_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||||
|
send_addr.sin_port = ra->local_port;
|
||||||
|
|
||||||
|
if(sendto(router->udp_sock, (char*)rp_header, sizeof(*rp_header) + len, 0, (struct sockaddr*)&send_addr, sizeof(send_addr)) == -1)
|
||||||
|
{
|
||||||
log_printf(LOG_ERROR, "Error relaying packet: %s", w32_error(WSAGetLastError()));
|
log_printf(LOG_ERROR, "Error relaying packet: %s", w32_error(WSAGetLastError()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ra = ra->next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LeaveCriticalSection(&(router->crit_sec));
|
LeaveCriticalSection(&(router->crit_sec));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user