Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Android] NetworkInterface.GetAllNetworkInterfaces() returns strange values on Android 11 + IPv6 #6973

Closed
Eilon opened this issue Apr 29, 2022 · 11 comments · Fixed by dotnet/runtime#71943, dotnet/runtime#76370 or dotnet/runtime#76541
Assignees
Labels
Area: Mono Runtime Mono-related issues: BCL bugs, AOT issues, etc.

Comments

@Eilon
Copy link
Member

Eilon commented Apr 29, 2022


Issue moved from dotnet/maui#6649


From @MartinRothschink on Friday, April 29, 2022 7:05:05 AM

Description

All tests have been done on a Xaomi Pad 5 (physical device, Android 11).

If target sdk is set to < 30, the values returned by NetworkInterface.GetAllNetworkInterfaces() seem valid:
ipv6-28

If target sdk is set to 31, the values returned by NetworkInterface.GetAllNetworkInterfaces() are outside of the enum ranges and name/description are empty. This screen shot shows the situation if IPv6 is not enabled in the router:
ipv4-31

If IPv6 is enabled in the router, NetworkInterfaceType and OperationalStatus values are even worse.
ipv6-31

Steps to Reproduce

  1. Create a new Maui app (VS 2022 17.2 Preview 5)
  2. Replace MainPage with the files below

MainPage.xaml.cs

namespace MauiApp1;

using System.Net.NetworkInformation;

public partial class MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent();
        LoadNics();
        BindingContext = this;
    }

    public Nic[] Nics { get; set; }

    private void LoadNics()
    {
        var nics = new List<Nic>();
        var ifs = NetworkInterface.GetAllNetworkInterfaces();
        foreach (var i in ifs)
        {
            var n = new Nic
            {
                Name = i.Name,
                Description = i.Description,
                Status = i.OperationalStatus,
                Type = i.NetworkInterfaceType
            };

            if (i.Supports(NetworkInterfaceComponent.IPv4))
                n.Supports += "IPv4 ";
            if (i.Supports(NetworkInterfaceComponent.IPv6))
                n.Supports += "IPv6 ";

            foreach (var a in i.GetIPProperties().UnicastAddresses)
            {
                if (a.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6)
                    n.IPv6Addresses += a.Address.ToString() + " ";

                if (a.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                    n.IPv4Addresses += a.Address.ToString() + " ";
            }

            nics.Add(n);
        }

        Nics = nics.ToArray();
    }
}


public class Nic
{
    public string Name { get; set; }
    public string Description { get; set; }
    public OperationalStatus Status { get; set; }
    public NetworkInterfaceType Type { get; set; }
    public string Supports { get; set;}
    public string IPv4Addresses { get; set; }
    public string IPv6Addresses { get; set; }
}

MainPage.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MauiApp1.MainPage">

    <ListView ItemsSource="{Binding Nics, Mode=OneWay}" SelectionMode="None" RowHeight="{OnPlatform Android=140}">
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <Grid ColumnSpacing="8">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto" />
                            <RowDefinition Height="Auto" />
                            <RowDefinition Height="Auto" />
                            <RowDefinition Height="Auto" />
                            <RowDefinition Height="Auto" />
                            <RowDefinition Height="Auto" />
                            <RowDefinition Height="Auto" />
                        </Grid.RowDefinitions>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto" />
                            <ColumnDefinition Width="Auto" />
                            <ColumnDefinition Width="Auto" />
                        </Grid.ColumnDefinitions>
                        <Label Grid.Column="0" Grid.Row="0" Text="Name" FontAttributes="Bold" FontSize="Subtitle"/>
                        <Label Grid.Column="1" Grid.Row="0" Grid.ColumnSpan="2" Text="{Binding Name}" FontSize="Subtitle"/>
                        <Label Grid.Column="1" Grid.Row="1" Text="Description" />
                        <Label Grid.Column="2" Grid.Row="1" Text="{Binding Description}" />
                        <Label Grid.Column="1" Grid.Row="2" Text="Status" />
                        <Label Grid.Column="2" Grid.Row="2" Text="{Binding Status}" />
                        <Label Grid.Column="1" Grid.Row="3" Text="Type" />
                        <Label Grid.Column="2" Grid.Row="3" Text="{Binding Type}" />
                        <Label Grid.Column="1" Grid.Row="4" Text="Supports" />
                        <Label Grid.Column="2" Grid.Row="4" Text="{Binding Supports}" />
                        <Label Grid.Column="1" Grid.Row="5" Text="IPv4Addresses" />
                        <Label Grid.Column="2" Grid.Row="5" Text="{Binding IPv4Addresses}" />
                        <Label Grid.Column="1" Grid.Row="6" Text="IPv6Addresses" />
                        <Label Grid.Column="2" Grid.Row="6" Text="{Binding IPv6Addresses}" />
                    </Grid>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</ContentPage>

Version with bug

Release Candidate 2 (current)

Last version that worked well

Unknown/Other

Affected platforms

Android

Affected platform versions

Android 10/11 (target sdk >= 30)

Did you find any workaround?

Currently I have to ignore the values for OperationalStatus and use the interface with valid UnicastAddresses.

Relevant log output

No response

@Eilon
Copy link
Member Author

Eilon commented Apr 29, 2022


Issue moved from dotnet/maui#6649


From @v-longmin on Friday, April 29, 2022 7:51:12 AM

Verified repro on Android 12.0 with VS 17.3.0 Preview 1.0 [32427.455.main]. Repro with above project.

@Eilon
Copy link
Member Author

Eilon commented Apr 29, 2022


Issue moved from dotnet/maui#6649


From @Eilon on Friday, April 29, 2022 5:41:03 PM

@jonathanpeppers - should this go to Xamarin Android? Or dotnet/runtime?

@Eilon
Copy link
Member Author

Eilon commented Apr 29, 2022


Issue moved from dotnet/maui#6649


From @jonathanpeppers on Friday, April 29, 2022 6:26:18 PM

I would send this to xamarin/xamarin-android, thanks.

We have some code there that passes these values to the BCL.

@philipag
Copy link

philipag commented Jul 5, 2022

@jonathanpeppers @grendello It seems that this works normally on some older phones with Android 8.0 but returns bad values on newer versions of Android. I hope that helps.

Any idea when this might be fixed?

@grendello
Copy link
Contributor

@philipag I'm afraid it might be hard to fix. Newer Android versions clamped down on the information available to "untrusted" apps and some information might be available only via the relevant Java API (you can access it via our bindings, of course). GetAllNetworkInterfaces() eventually uses Linux netlink protocol which may be severely restricted for some versions of Android :(

Please follow the steps below and attach the resulting logcat.txt, it might help us see system errors, if any:

$ adb shell setprop debug.mono.log default,netlink
$ adb logcat -G 16M
$ adb logcat -c
# Run the app here
$ adb logcat -d > logcat.txt

@philipag
Copy link

philipag commented Jul 5, 2022

@grendello Here is the resulting log. The app name is "testapp".

logcat.zip

@grendello
Copy link
Contributor

@philipag thanks! Unfortunately, it seems our netlink code isn't used in your app. The only netlink messages I see are:

07-05 14:01:29.315   957  2594 W NetlinkSocket: maximum read
07-05 14:01:29.315   957  2594 W NetlinkSocket: maximum read
07-05 14:01:29.328   957  2594 W NetlinkSocket: maximum read
07-05 14:01:29.328   957  2594 W NetlinkSocket: maximum read
07-05 14:01:29.378   957  2594 W NetlinkSocket: maximum read
07-05 14:01:29.379   957  2594 W NetlinkSocket: maximum read
07-05 14:01:29.416   957  2594 W NetlinkSocket: maximum read
07-05 14:01:29.691   957  2594 W NetlinkSocket: maximum read
07-05 14:01:31.400   957  2594 W NetlinkSocket: maximum read
07-05 14:01:31.411   957  2594 W NetlinkSocket: maximum read
07-05 14:01:31.411   957  2594 W NetlinkSocket: maximum read
07-05 14:01:31.418   957  2594 W NetlinkSocket: maximum read
07-05 14:01:31.419   957  2594 W NetlinkSocket: maximum read
07-05 14:01:31.420   957  2594 W NetlinkSocket: maximum read
07-05 14:01:31.420   957  2594 W NetlinkSocket: maximum read
07-05 14:01:31.424   957  2594 W NetlinkSocket: maximum read
07-05 14:01:31.425   957  2594 W NetlinkSocket: maximum read
07-05 14:01:31.425   957  2594 W NetlinkSocket: maximum read
07-05 14:01:31.425   957  2594 W NetlinkSocket: maximum read
07-05 14:01:31.426   957  2594 W NetlinkSocket: maximum read
07-05 14:01:31.426   957  2594 W NetlinkSocket: maximum read
07-05 14:01:31.426   957  2594 W NetlinkSocket: maximum read
07-05 14:01:31.426   957  2594 W NetlinkSocket: maximum read
07-05 14:01:31.426   957  2594 W NetlinkSocket: maximum read
07-05 14:01:31.426   957  2594 W NetlinkSocket: maximum read
07-05 14:01:31.426   957  2594 W NetlinkSocket: maximum read
07-05 14:01:31.445   957  2594 W NetlinkSocket: maximum read
07-05 14:01:31.446   957  2594 W NetlinkSocket: maximum read
07-05 14:01:34.496   957  2594 W NetlinkSocket: maximum read
07-05 14:01:34.498   957  2594 W NetlinkSocket: maximum read
07-05 14:01:34.498   957  2594 W NetlinkSocket: maximum read
07-05 14:01:34.498   957  2594 W NetlinkSocket: maximum read

Which looks like some kind of throttling (?), possibly triggered by the new network interface enumeration code in dotnet runtime.

@simonrozsival would you mind taking a look?

@grendello grendello added Area: Mono Runtime Mono-related issues: BCL bugs, AOT issues, etc. and removed Area: App Runtime Issues in `libmonodroid.so`. labels Jul 5, 2022
@jonpryor jonpryor assigned jonpryor and simonrozsival and unassigned jonpryor Jul 5, 2022
@simonrozsival
Copy link
Member

I can confirm that GetAllNetworkInterfaces() returns invalid data on new Android versions. As a workaround, it's possible to use platform specific APIs to enumerate the interfaces:

var ifaces = Java.Net.NetworkInterface.NetworkInterfaces;
while (ifaces.HasMoreElements)
{
        var iface = ifaces.NextElement().JavaCast<Java.Net.NetworkInterface>();
        // ...
}

.NET internally uses the libc getifaddrs function to get the network interfaces information. We should consider rewriting this functionality with JNI and get the infromation from the Android APIs.

@grendello
Copy link
Contributor

@simonrozsival XA has an implementation of getifaddrs based on the netlink protocol, would you be able to test if it works? I wonder if it's the bionic's getifaddrs that's limited and not netlink itself (it's likely that both are limited and one has to go through Java interfaces which have correct privileges to obtain the information)

@simonrozsival
Copy link
Member

@grendello I'll give it a try.

@simonrozsival
Copy link
Member

The network interfaces' information is accessible through netlink so I ported the XA implementation into dotnet/runtime.

steveisok pushed a commit to dotnet/runtime that referenced this issue Jul 12, 2022
In recent Android versions the data returned by getifaddrs is invalid and doesn't allow us to implement System.Net.NetworkInformation.GetAllNetworkInterfaces(). It's possible to reimplement getifaddrs using Netlink and there's already an existing implementation in Xamarin.Android.

Fixes dotnet/android#6973
Ref #62780
Ref #51303
@ghost ghost locked as resolved and limited conversation to collaborators Aug 12, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.