From: Hans Leidekker hans@codeweavers.com
--- dlls/wpcap/unixlib.h | 14 ++--- dlls/wpcap/wpcap.c | 129 ++++++++++++++++++++++++++++++------------- 2 files changed, 94 insertions(+), 49 deletions(-)
diff --git a/dlls/wpcap/unixlib.h b/dlls/wpcap/unixlib.h index 8cd64ef0210..18854e0b86b 100644 --- a/dlls/wpcap/unixlib.h +++ b/dlls/wpcap/unixlib.h @@ -17,18 +17,13 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-struct sockaddr_hdr -{ - unsigned short sa_family; -}; - struct pcap_address { struct pcap_address *next; - struct sockaddr_hdr *addr; - struct sockaddr_hdr *netmask; - struct sockaddr_hdr *broadaddr; - struct sockaddr_hdr *dstaddr; + struct sockaddr *addr; + struct sockaddr *netmask; + struct sockaddr *broadaddr; + struct sockaddr *dstaddr; };
struct pcap_interface @@ -57,7 +52,6 @@ struct pcap struct pcap_pkthdr_win32 hdr; };
- struct compile_params { struct pcap *pcap; diff --git a/dlls/wpcap/wpcap.c b/dlls/wpcap/wpcap.c index df35954bfa7..f600b9ef066 100644 --- a/dlls/wpcap/wpcap.c +++ b/dlls/wpcap/wpcap.c @@ -26,6 +26,7 @@ #include "winsock2.h" #include "ws2ipdef.h" #include "iphlpapi.h" +#include "netioapi.h"
#include "wine/unixlib.h" #include "wine/debug.h" @@ -238,59 +239,109 @@ static char *build_win32_description( const struct pcap_interface *unix_dev ) return ret; }
-static struct sockaddr_hdr *dup_sockaddr( const struct sockaddr_hdr *addr ) +static struct sockaddr *get_address( const IP_ADAPTER_UNICAST_ADDRESS *addr ) { - struct sockaddr_hdr *ret; + struct sockaddr *ret; + if (!(ret = malloc( addr->Address.iSockaddrLength ))) return NULL; + memcpy( ret, addr->Address.lpSockaddr, addr->Address.iSockaddrLength ); + return ret; +} + +static void convert_length_to_ipv6_mask( ULONG length, IN6_ADDR *mask ) +{ + unsigned int i; + for (i = 0; i < length / 8; i++) mask->u.Byte[i] = 0xff; + mask->u.Byte[i] = 0xff << (8 - length % 8); +} + +static struct sockaddr *get_netmask( const IP_ADAPTER_UNICAST_ADDRESS *addr ) +{ + struct sockaddr *ret;
- switch (addr->sa_family) + switch (addr->Address.lpSockaddr->sa_family) { case AF_INET: { - struct sockaddr_in *dst, *src = (struct sockaddr_in *)addr; - if (!(dst = calloc( 1, sizeof(*dst) ))) return NULL; - dst->sin_family = src->sin_family; - dst->sin_port = src->sin_port; - dst->sin_addr = src->sin_addr; - ret = (struct sockaddr_hdr *)dst; + struct sockaddr_in *netmask_addr_in; + + if (!(netmask_addr_in = calloc( 1, sizeof(*netmask_addr_in) ))) return NULL; + netmask_addr_in->sin_family = AF_INET; + ConvertLengthToIpv4Mask( addr->OnLinkPrefixLength, &netmask_addr_in->sin_addr.S_un.S_addr ); + ret = (struct sockaddr *)netmask_addr_in; break; } case AF_INET6: { - struct sockaddr_in6 *dst, *src = (struct sockaddr_in6 *)addr; - if (!(dst = malloc( sizeof(*dst) ))) return NULL; - dst->sin6_family = src->sin6_family; - dst->sin6_port = src->sin6_port; - dst->sin6_flowinfo = src->sin6_flowinfo; - dst->sin6_addr = src->sin6_addr; - dst->sin6_scope_id = src->sin6_scope_id; - ret = (struct sockaddr_hdr *)dst; + struct sockaddr_in6 *netmask_addr_in6; + + if (!(netmask_addr_in6 = calloc( 1, sizeof(*netmask_addr_in6) ))) return NULL; + netmask_addr_in6->sin6_family = AF_INET6; + convert_length_to_ipv6_mask( addr->OnLinkPrefixLength, &netmask_addr_in6->sin6_addr ); + ret = (struct sockaddr *)netmask_addr_in6; break; } default: - FIXME( "address family %u not supported\n", addr->sa_family ); + FIXME( "address family %u not supported\n", addr->Address.lpSockaddr->sa_family ); return NULL; }
return ret; }
-static struct pcap_address *build_win32_address( struct pcap_address *src ) +static struct sockaddr *get_broadcast( const IP_ADAPTER_UNICAST_ADDRESS *addr ) { - struct pcap_address *dst; + struct sockaddr *ret;
- if (!(dst = calloc( 1, sizeof(*dst) ))) return NULL; - if (src->addr && !(dst->addr = dup_sockaddr( src->addr ))) goto err; - if (src->netmask && !(dst->netmask = dup_sockaddr( src->netmask ))) goto err; - if (src->broadaddr && !(dst->broadaddr = dup_sockaddr( src->broadaddr ))) goto err; - if (src->dstaddr && !(dst->dstaddr = dup_sockaddr( src->dstaddr ))) goto err; - return dst; + switch (addr->Address.lpSockaddr->sa_family) + { + case AF_INET: + { + struct sockaddr_in *broadcast_addr_in, *addr_in = (struct sockaddr_in *)addr->Address.lpSockaddr; + ULONG netmask; + + if (!(broadcast_addr_in = calloc( 1, sizeof(*broadcast_addr_in) ))) return FALSE; + broadcast_addr_in->sin_family = AF_INET; + ConvertLengthToIpv4Mask( addr->OnLinkPrefixLength, &netmask ); + broadcast_addr_in->sin_addr.S_un.S_addr = addr_in->sin_addr.S_un.S_addr | ~netmask; + ret = (struct sockaddr *)broadcast_addr_in; + break; + } + case AF_INET6: + { + struct sockaddr_in6 *broadcast_addr_in6, *addr_in6 = (struct sockaddr_in6 *)addr->Address.lpSockaddr; + IN6_ADDR netmask, *address = (IN6_ADDR *)&addr_in6->sin6_addr; + unsigned int i; + + if (!(broadcast_addr_in6 = calloc( 1, sizeof(*broadcast_addr_in6) ))) return NULL; + broadcast_addr_in6->sin6_family = AF_INET6; + convert_length_to_ipv6_mask( addr->OnLinkPrefixLength, &netmask ); + for (i = 0; i < 8; i++) broadcast_addr_in6->sin6_addr.u.Word[i] = address->u.Word[i] | ~netmask.u.Word[i]; + ret = (struct sockaddr *)broadcast_addr_in6; + break; + } + default: + FIXME( "address family %u not supported\n", addr->Address.lpSockaddr->sa_family ); + return NULL; + } + + return ret; +} + +static struct pcap_address *build_win32_address( const IP_ADAPTER_UNICAST_ADDRESS *addr ) +{ + struct pcap_address *ret; + + if (!(ret = calloc( 1, sizeof(*ret) ))) return NULL; + if (!(ret->addr = get_address( addr ))) goto err; + if (!(ret->netmask = get_netmask( addr ))) goto err; + if (!(ret->broadaddr = get_broadcast( addr ))) goto err; + return ret;
err: - free( dst->addr ); - free( dst->netmask ); - free( dst->broadaddr ); - free( dst->dstaddr ); - free( dst ); + free( ret->addr ); + free( ret->netmask ); + free( ret->broadaddr ); + free( ret ); return NULL; }
@@ -305,27 +356,27 @@ static void add_win32_address( struct pcap_address **list, struct pcap_address * } }
-static struct pcap_address *build_win32_addresses( struct pcap_address *addrs ) +static struct pcap_address *build_win32_addresses( const IP_ADAPTER_ADDRESSES *adapter ) { - struct pcap_address *src, *dst, *ret = NULL; - src = addrs; + struct pcap_address *dst, *ret = NULL; + IP_ADAPTER_UNICAST_ADDRESS *src = adapter->FirstUnicastAddress; while (src) { if ((dst = build_win32_address( src ))) add_win32_address( &ret, dst ); - src = src->next; + src = src->Next; } return ret; }
static struct pcap_interface *build_win32_device( const struct pcap_interface *unix_dev, const char *source, - const char *adapter_name ) + const IP_ADAPTER_ADDRESSES *adapter ) { struct pcap_interface *ret;
if (!(ret = calloc( 1, sizeof(*ret) ))) return NULL; - if (!(ret->name = build_win32_name( source, adapter_name ))) goto err; + if (!(ret->name = build_win32_name( source, adapter->AdapterName ))) goto err; if (!(ret->description = build_win32_description( unix_dev ))) goto err; - ret->addresses = build_win32_addresses( unix_dev->addresses ); + ret->addresses = build_win32_addresses( adapter ); ret->flags = unix_dev->flags; return ret;
@@ -366,7 +417,7 @@ static int find_all_devices( const char *source, struct pcap_interface **devs, c cur = unix_devs; while (cur) { - if ((ptr = find_adapter( adapters, cur->name )) && (dev = build_win32_device( cur, source, ptr->AdapterName ))) + if ((ptr = find_adapter( adapters, cur->name )) && (dev = build_win32_device( cur, source, ptr ))) { add_win32_device( &win32_devs, dev ); }
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=125502
Your paranoid android.
=== debian11 (32 bit report) ===
winmm: midi: Timeout