Skip to content

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

Description

@Eilon

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

Activity

  1. Eilon commented on Apr 29, 2022

    @Eilon
    Author

    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.

  2. Eilon commented on Apr 29, 2022

    @Eilon
    Author

    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?

  3. Eilon commented on Apr 29, 2022

    @Eilon
    Author

    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.

  4. philipag commented on Jul 5, 2022

    @philipag

    @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?

  5. grendello commented on Jul 5, 2022

    @grendello
    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
  6. philipag commented on Jul 5, 2022

    @philipag

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

    logcat.zip

  7. grendello commented on Jul 5, 2022

    @grendello
    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?

  8. added
    Area: Mono RuntimeMono-related issues: BCL bugs, AOT issues, etc.
    and removed on Jul 5, 2022
  9. simonrozsival commented on Jul 7, 2022

    @simonrozsival
    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.

  10. grendello commented on Jul 7, 2022

    @grendello
    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)

  11. simonrozsival commented on Jul 7, 2022

    @simonrozsival
    Member

    @grendello I'll give it a try.

  12. simonrozsival commented on Jul 11, 2022

    @simonrozsival
    Member

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

  13. added a commit that references this issue on Jul 12, 2022
    1de4a5c
  14. ghost locked as resolved and limited conversation to collaborators on Aug 12, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Area: Mono RuntimeMono-related issues: BCL bugs, AOT issues, etc.

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions