Unfortunately VPN interfaces I am observing here don't expose any definite type in ifr_hwaddr.sa_data (having ARPHRD_NONE). But the flags from SIOCGIFFLAGS have IFF_POINTOPOINT for such interfaces, so it is probably nothing wrong in guessing the iface type as PPP if the flag is set.
Fixes Creativerse hanging on creating local game when there is a VPN interface.
From: Paul Gofman pgofman@codeweavers.com
--- dlls/nsiproxy.sys/ndis.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/dlls/nsiproxy.sys/ndis.c b/dlls/nsiproxy.sys/ndis.c index c34630d8aec..5658b72b79a 100644 --- a/dlls/nsiproxy.sys/ndis.c +++ b/dlls/nsiproxy.sys/ndis.c @@ -170,13 +170,19 @@ static NTSTATUS if_get_physical( const char *name, UINT *type, IF_PHYSICAL_ADDRE break; }
+ TRACE( "iface %s, sa_family %u.\n", ifr.ifr_name, ifr.ifr_hwaddr.sa_family ); + if (*type == MIB_IF_TYPE_OTHER && !ioctl( fd, SIOCGIFFLAGS, &ifr )) + { + TRACE( "flags %#x.\n", ifr.ifr_flags ); + if (ifr.ifr_flags & IFF_POINTOPOINT) *type = MIB_IF_TYPE_PPP; + } + err: close( fd ); return ret; }
#elif defined (HAVE_SYS_SYSCTL_H) && defined (HAVE_NET_IF_DL_H) - static NTSTATUS if_get_physical( const char *name, UINT *type, IF_PHYSICAL_ADDRESS *phys_addr ) { struct if_msghdr *ifm;
I think `MIB_IF_TYPE_PPP` means a [Point-to-Point protocol](https://en.wikipedia.org/wiki/Point-to-Point_Protocol) interface (like what we used to use for dialup), whereas the Linux `IFF_POINTOPOINT` means that an interface is "a direct link between two machines with nobody else listening on it" (see the `ifconfig(8)` man page).
But even though VPN interfaces are of course not using PPP, for some reason Windows actually does advertise them as `IF_TYPE_PPP`. [Chromium](https://source.chromium.org/chromium/chromium/src/+/main:net/dns/dns_config_...) searches for `IF_TYPE_PPP` interfaces to detect whether a VPN is running.
(I also took a look at the Wireguard-NT source, it advertises itself as [`IF_TYPE_PROP_VIRTUAL`](https://git.zx2c4.com/wireguard-nt/tree/driver/device.c#n479) but I guess Windows squashes that down into `MIB_IF_TYPE_PPP` for `GetAdaptersAddresses()`)
It't not obvious at all, but this does seem to be correct for VPN interfaces. Looking at the Linux source, wireguard and tun interfaces both use `ARPHRD_NONE`+`IFF_POINTOPOINT`, and `IF_TYPE_PPP` is the right Windows type for those.
Huw Davies (@huw) commented about dlls/nsiproxy.sys/ndis.c:
break; }
- TRACE( "iface %s, sa_family %u.\n", ifr.ifr_name, ifr.ifr_hwaddr.sa_family );
- if (*type == MIB_IF_TYPE_OTHER && !ioctl( fd, SIOCGIFFLAGS, &ifr ))
- {
TRACE( "flags %#x.\n", ifr.ifr_flags );
if (ifr.ifr_flags & IFF_POINTOPOINT) *type = MIB_IF_TYPE_PPP;
- }
Could we remove the `TRACE()`s here?
Huw Davies (@huw) commented about dlls/nsiproxy.sys/ndis.c:
}
- TRACE( "iface %s, sa_family %u.\n", ifr.ifr_name, ifr.ifr_hwaddr.sa_family );
- if (*type == MIB_IF_TYPE_OTHER && !ioctl( fd, SIOCGIFFLAGS, &ifr ))
- {
TRACE( "flags %#x.\n", ifr.ifr_flags );
if (ifr.ifr_flags & IFF_POINTOPOINT) *type = MIB_IF_TYPE_PPP;
- }
err: close( fd ); return ret; }
#elif defined (HAVE_SYS_SYSCTL_H) && defined (HAVE_NET_IF_DL_H)
This whitespace change seems gratuitous, please leave the blank line.
Could you include some of the MR description comments in the actual commit message?