Erich Hoover : ws2_32: Fix interface-bound filter to accept locally generated targeted packets.

Alexandre Julliard julliard at winehq.org
Tue Jun 25 14:41:25 CDT 2013


Module: wine
Branch: master
Commit: 74010aa0e774b8b4e32455e6a42306f714ee66dd
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=74010aa0e774b8b4e32455e6a42306f714ee66dd

Author: Erich Hoover <ehoover at mines.edu>
Date:   Sun Jun 23 20:19:16 2013 -0600

ws2_32: Fix interface-bound filter to accept locally generated targeted packets.

---

 dlls/ws2_32/socket.c |   13 ++++++++++++-
 1 files changed, 12 insertions(+), 1 deletions(-)

diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index 98bb426..7ad118f 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -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)




More information about the wine-cvs mailing list