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 sock_filter iface_memaddr;
|
||||
struct sock_filter iface_rule;
|
||||
struct sock_filter ip_memaddr;
|
||||
struct sock_filter ip_rule;
|
||||
struct sock_filter return_keep;
|
||||
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) \
|
||||
-offsetof(struct interface_filter, here)-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 = {
|
||||
/* 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_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, 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 */
|
||||
specific_interface_filter = generic_interface_filter;
|
||||
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.filter = (struct sock_filter *) &specific_interface_filter;
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter_prog, sizeof(filter_prog)) != 0)
|
||||
|
|
Loading…
Reference in New Issue