From: Nikolai Abdusamatov <nick.luft.work@gmail.com> On macOS, gif0/stf0 and point-to-point IFT_OTHER interfaces inflate the NSI adapter table and break fixed-buffer GetAdaptersInfo callers. Use getifaddrs()/AF_LINK to identify them by BSD type and flags in nsiproxy.sys. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=59614 --- dlls/nsiproxy.sys/ndis.c | 64 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 2 deletions(-) diff --git a/dlls/nsiproxy.sys/ndis.c b/dlls/nsiproxy.sys/ndis.c index 8c15186ed53..84a4d65a493 100644 --- a/dlls/nsiproxy.sys/ndis.c +++ b/dlls/nsiproxy.sys/ndis.c @@ -30,6 +30,10 @@ #include <sys/ioctl.h> #include <unistd.h> +#ifdef HAVE_IFADDRS_H +#include <ifaddrs.h> +#endif + #ifdef HAVE_NET_IF_H #include <net/if.h> #endif @@ -66,6 +70,10 @@ #include <linux/wireless.h> #endif +#if defined(HAVE_IFADDRS_H) && defined(HAVE_NET_IF_DL_H) && defined(HAVE_NET_IF_TYPES_H) +#define HAVE_BSD_IF_INFO 1 +#endif + #include <pthread.h> #include "ntstatus.h" @@ -274,11 +282,48 @@ static WCHAR *strdupAtoW( const char *str ) return ret; } -static struct if_entry *add_entry( UINT index, char *name ) +#ifdef HAVE_BSD_IF_INFO +static void if_get_bsd_info( const struct ifaddrs *ifaddrs, const char *name, UINT *bsd_type, UINT *bsd_flags ) +{ + const struct ifaddrs *entry; + + *bsd_type = 0; + *bsd_flags = 0; + + if (!ifaddrs) return; + + for (entry = ifaddrs; entry; entry = entry->ifa_next) + { + if (!entry->ifa_name || strcmp( entry->ifa_name, name )) continue; + if (!entry->ifa_addr || entry->ifa_addr->sa_family != AF_LINK) continue; + *bsd_type = ((const struct sockaddr_dl *)entry->ifa_addr)->sdl_type; + *bsd_flags = entry->ifa_flags; + return; + } +} + +static BOOL if_should_skip( UINT bsd_type, UINT bsd_flags ) +{ + if (bsd_type == IFT_GIF || bsd_type == IFT_STF) return TRUE; + if (bsd_type == IFT_OTHER && (bsd_flags & IFF_POINTOPOINT)) return TRUE; + + return FALSE; +} +#else +static BOOL if_should_skip( UINT bsd_type, UINT bsd_flags ) +{ + (void)bsd_type; + (void)bsd_flags; + return FALSE; +} +#endif + +static struct if_entry *add_entry( UINT index, char *name, UINT bsd_type, UINT bsd_flags ) { struct if_entry *entry; int name_len = strlen( name ); + if (if_should_skip( bsd_type, bsd_flags )) return NULL; if (name_len >= sizeof(entry->if_unix_name)) return NULL; entry = malloc( sizeof(*entry) ); if (!entry) return NULL; @@ -310,13 +355,28 @@ static unsigned int update_if_table( void ) { struct if_nameindex *indices = if_nameindex(), *entry; unsigned int append_count = 0; +#ifdef HAVE_BSD_IF_INFO + struct ifaddrs *ifaddrs = NULL; + if (getifaddrs( &ifaddrs ) != 0) ifaddrs = NULL; +#endif for (entry = indices; entry->if_index; entry++) { - if (!find_entry_from_index( entry->if_index ) && add_entry( entry->if_index, entry->if_name )) + UINT bsd_type; + UINT bsd_flags; + bsd_type = 0; + bsd_flags = 0; +#ifdef HAVE_BSD_IF_INFO + if_get_bsd_info( ifaddrs, entry->if_name, &bsd_type, &bsd_flags ); +#endif + if (!find_entry_from_index( entry->if_index ) && add_entry( entry->if_index, entry->if_name, bsd_type, bsd_flags )) ++append_count; } +#ifdef HAVE_BSD_IF_INFO + if (ifaddrs) freeifaddrs( ifaddrs ); +#endif + if_freenameindex( indices ); return append_count; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10553