ws2_32: Fix interface-bound filter to accept locally generated targeted packets.
This commit is contained in:
parent
c66d94bfd9
commit
74010aa0e7
|
@ -178,6 +178,8 @@ WINE_DECLARE_DEBUG_CHANNEL(winediag);
|
||||||
struct interface_filter {
|
struct interface_filter {
|
||||||
struct sock_filter iface_memaddr;
|
struct sock_filter iface_memaddr;
|
||||||
struct sock_filter iface_rule;
|
struct sock_filter iface_rule;
|
||||||
|
struct sock_filter ip_memaddr;
|
||||||
|
struct sock_filter ip_rule;
|
||||||
struct sock_filter return_keep;
|
struct sock_filter return_keep;
|
||||||
struct sock_filter return_dump;
|
struct sock_filter return_dump;
|
||||||
};
|
};
|
||||||
|
@ -187,9 +189,17 @@ struct interface_filter {
|
||||||
# define FILTER_JUMP_KEEP(here) (u_char)(offsetof(struct interface_filter, return_keep) \
|
# define FILTER_JUMP_KEEP(here) (u_char)(offsetof(struct interface_filter, return_keep) \
|
||||||
-offsetof(struct interface_filter, here)-sizeof(struct sock_filter)) \
|
-offsetof(struct interface_filter, here)-sizeof(struct sock_filter)) \
|
||||||
/sizeof(struct sock_filter)
|
/sizeof(struct sock_filter)
|
||||||
|
# define FILTER_JUMP_NEXT() (u_char)(0)
|
||||||
|
# define SKF_NET_DESTIP 16 /* offset in the network header to the destination IP */
|
||||||
static struct interface_filter generic_interface_filter = {
|
static struct interface_filter generic_interface_filter = {
|
||||||
|
/* This filter rule allows incoming packets on the specified interface, which works for all
|
||||||
|
* remotely generated packets and for locally generated broadcast packets. */
|
||||||
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, SKF_AD_OFF+SKF_AD_IFINDEX),
|
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, SKF_AD_OFF+SKF_AD_IFINDEX),
|
||||||
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0xdeadbeef, FILTER_JUMP_KEEP(iface_rule), FILTER_JUMP_DUMP(iface_rule)),
|
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0xdeadbeef, FILTER_JUMP_KEEP(iface_rule), FILTER_JUMP_NEXT()),
|
||||||
|
/* This rule allows locally generated packets targeted at the specific IP address of the chosen
|
||||||
|
* adapter (local packets not destined for the broadcast address do not have IFINDEX set) */
|
||||||
|
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, SKF_NET_OFF+SKF_NET_DESTIP),
|
||||||
|
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0xdeadbeef, FILTER_JUMP_KEEP(ip_rule), FILTER_JUMP_DUMP(ip_rule)),
|
||||||
BPF_STMT(BPF_RET+BPF_K, (u_int)-1), /* keep packet */
|
BPF_STMT(BPF_RET+BPF_K, (u_int)-1), /* keep packet */
|
||||||
BPF_STMT(BPF_RET+BPF_K, 0) /* dump packet */
|
BPF_STMT(BPF_RET+BPF_K, 0) /* dump packet */
|
||||||
};
|
};
|
||||||
|
@ -2191,6 +2201,7 @@ static BOOL interface_bind( SOCKET s, int fd, struct sockaddr *addr )
|
||||||
goto cleanup; /* Failed to suggest egress interface */
|
goto cleanup; /* Failed to suggest egress interface */
|
||||||
specific_interface_filter = generic_interface_filter;
|
specific_interface_filter = generic_interface_filter;
|
||||||
specific_interface_filter.iface_rule.k = adapter->Index;
|
specific_interface_filter.iface_rule.k = adapter->Index;
|
||||||
|
specific_interface_filter.ip_rule.k = htonl(adapter_addr);
|
||||||
filter_prog.len = sizeof(generic_interface_filter)/sizeof(struct sock_filter);
|
filter_prog.len = sizeof(generic_interface_filter)/sizeof(struct sock_filter);
|
||||||
filter_prog.filter = (struct sock_filter *) &specific_interface_filter;
|
filter_prog.filter = (struct sock_filter *) &specific_interface_filter;
|
||||||
if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter_prog, sizeof(filter_prog)) != 0)
|
if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter_prog, sizeof(filter_prog)) != 0)
|
||||||
|
|
Loading…
Reference in New Issue