From: Marc-Aurel Zent marc_aurel@me.com
...in unixlib before duplicationg it on the PE side. --- dlls/wpcap/unixlib.c | 40 ++++++++++++++++++++++++++++++++++++++++ dlls/wpcap/unixlib.h | 1 + dlls/wpcap/wpcap.c | 14 +++++++------- 3 files changed, 48 insertions(+), 7 deletions(-)
diff --git a/dlls/wpcap/unixlib.c b/dlls/wpcap/unixlib.c index a44627a7754..ae850efb677 100644 --- a/dlls/wpcap/unixlib.c +++ b/dlls/wpcap/unixlib.c @@ -34,6 +34,12 @@ #include "windef.h" #include "winbase.h" #include "winternl.h" +#define USE_WS_PREFIX +/* the following 2 libpcap defines interfere with winsock2.h */ +#undef SOCKET +#undef INVALID_SOCKET +#include "winsock2.h" +#include "ws2ipdef.h"
#include "wine/unixlib.h" #include "wine/debug.h" @@ -42,6 +48,39 @@ WINE_DEFAULT_DEBUG_CHANNEL(wpcap); WINE_DECLARE_DEBUG_CHANNEL(winediag);
+static NTSTATUS convert_sockaddr( void *args ) +{ + struct sockaddr_storage *addr = args; + struct sockaddr_storage unix_addr = *addr; + + switch (unix_addr.ss_family) + { + case AF_INET: + { + struct sockaddr_in *src = (struct sockaddr_in *)&unix_addr; + SOCKADDR_IN *dst = (SOCKADDR_IN *)addr; + dst->sin_family = WS_AF_INET; + dst->sin_port = (USHORT)src->sin_port; + memcpy(&dst->sin_addr, &src->sin_addr, sizeof(IN_ADDR)); + return STATUS_SUCCESS; + } + case AF_INET6: + { + struct sockaddr_in6 *src = (struct sockaddr_in6 *)&unix_addr; + SOCKADDR_IN6 *dst = (SOCKADDR_IN6 *)addr; + dst->sin6_family = WS_AF_INET6; + dst->sin6_port = (USHORT)src->sin6_port; + dst->sin6_flowinfo = (ULONG)src->sin6_flowinfo; + memcpy(&dst->sin6_addr, &src->sin6_addr, sizeof(IN6_ADDR)); + dst->sin6_scope_id = (ULONG)src->sin6_scope_id; + return STATUS_SUCCESS; + } + default: + FIXME( "unix address family %u not supported\n", unix_addr.ss_family ); + return STATUS_NOT_IMPLEMENTED; + } +} + static NTSTATUS wrap_activate( void *args ) { struct pcap *pcap = args; @@ -372,6 +411,7 @@ static NTSTATUS wrap_tstamp_type_val_to_name( void *args )
const unixlib_entry_t __wine_unix_call_funcs[] = { + convert_sockaddr, wrap_activate, wrap_breakloop, wrap_can_set_rfmon, diff --git a/dlls/wpcap/unixlib.h b/dlls/wpcap/unixlib.h index 9ebcf225c5d..e953bcb6911 100644 --- a/dlls/wpcap/unixlib.h +++ b/dlls/wpcap/unixlib.h @@ -263,6 +263,7 @@ struct tstamp_type_val_to_name_params
enum pcap_funcs { + unix_convert_sockaddr, unix_activate, unix_breakloop, unix_can_set_rfmon, diff --git a/dlls/wpcap/wpcap.c b/dlls/wpcap/wpcap.c index 0e6c55d4904..5fe27984ff4 100644 --- a/dlls/wpcap/wpcap.c +++ b/dlls/wpcap/wpcap.c @@ -238,12 +238,15 @@ static char *build_win32_description( const struct pcap_interface *unix_dev ) return ret; }
-static struct pcap_sockaddr *dup_sockaddr( const struct pcap_sockaddr *addr ) +static struct pcap_sockaddr *dup_sockaddr( struct pcap_sockaddr *addr ) { - struct pcap_sockaddr *ret; - short sa_family = *((short *)addr); + struct pcap_sockaddr *ret = NULL; + unsigned short ss_family;
- switch (sa_family) + if (PCAP_CALL( convert_sockaddr, addr )) return NULL; + ss_family = ((struct sockaddr_storage *)addr)->ss_family; + + switch (ss_family) { case AF_INET: { @@ -267,9 +270,6 @@ static struct pcap_sockaddr *dup_sockaddr( const struct pcap_sockaddr *addr ) ret = (struct pcap_sockaddr *)dst; break; } - default: - FIXME( "address family %d not supported\n", sa_family ); - return NULL; }
return ret;