Search Unity

Resolved Not getting the correct Local IP on phones

Discussion in 'Netcode for GameObjects' started by GuirieSanchez, Jan 19, 2023.

  1. GuirieSanchez

    GuirieSanchez

    Joined:
    Oct 12, 2021
    Posts:
    452
    I've only been able to test it on 2 iPhones, but they do not report the correct local IP when not connected to the WiFi (just by using 4G / data). I'm getting a blank string, unless a client is connected to their 4G, in which case it shows their correct local IP, which is weird.

    I'm getting the text (string) with this function:

    Code (CSharp):
    1. public static string[] GetLocalIPv4(NetworkInterfaceType interfaceType = NetworkInterfaceType.Ethernet)
    2.         {
    3.             var ipAddrList = new List<string>();
    4.             foreach (var netInterface in NetworkInterface.GetAllNetworkInterfaces())
    5.             {
    6.                 if (netInterface.NetworkInterfaceType == interfaceType && netInterface.OperationalStatus == OperationalStatus.Up)
    7.                 {
    8.                     foreach (var ip in netInterface.GetIPProperties().UnicastAddresses)
    9.                     {
    10.                         if (ip.Address.AddressFamily == AddressFamily.InterNetwork)
    11.                             ipAddrList.Add(ip.Address.ToString());
    12.                     }
    13.                 }
    14.             }
    15.             return ipAddrList.ToArray();
    16.         }
    Then, when starting the host, it calls these 2 functions:
    Code (CSharp):
    1. SetTransportConnectionData(NetcodeUtils.GetFirstLocalIPv4());
    2.             SetConnectionPayload();
    The first one being:

    Code (CSharp):
    1. public static string GetFirstLocalIPv4(NetworkInterfaceType interfaceType = NetworkInterfaceType.Ethernet) =>
    2.             GetLocalIPv4(interfaceType)?.FirstOrDefault();
    which calls for the same first function that I write at the very beginning.
     
    Last edited: Jan 19, 2023
  2. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    6,005
    Did you check the phone settings for its actual IP and compare that? If the phone doesn‘t show it, check the router they are connected to via Wifi.

    Keep in mind that they may be using an IPv6 address and that there are two addresses: one for Wifi and one for cellular data. Try logging all of the addresses you are able to obtain, find the ones that are correct, then come up with a scheme and test it on multiple devices.
     
    GuirieSanchez likes this.
  3. GuirieSanchez

    GuirieSanchez

    Joined:
    Oct 12, 2021
    Posts:
    452
    Interestingly enough, the "GetLocalIPv4" doesn't seem to work at all when the data is connected. I'm reporting a list of strings that I get from the following list:

    Code (CSharp):
    1. if (ip.Address.AddressFamily == AddressFamily.InterNetwork)
    2.                         {
    3.                             ipAddrList.Add(ip.Address.ToString());
    4.                         }
    The "NetcodeUtils.GetLocalIPv4()?.Count()" is 1, with the correct local IP address when solely connected to the WiFi. But if the phone is connected to 4G, then the list count is 0, and the strings reported are null, as one would expect. This makes me think that, as you said, a phone's data might be using an IPv6. Before I was using this piece of code:

    Code (CSharp):
    1.  public static string GetIP(ADDRESSFAM Addfam)
    2.         {
    3.             //Return null if ADDRESSFAM is Ipv6 but Os does not support it
    4.             if (Addfam == ADDRESSFAM.IPv6 && !Socket.OSSupportsIPv6)
    5.             {
    6.                 return null;
    7.             }
    8.  
    9.             string output = "0.0.0.0";
    10.  
    11.             foreach (NetworkInterface item in NetworkInterface.GetAllNetworkInterfaces())
    12.             {
    13. #if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN
    14.                 NetworkInterfaceType _type1 = NetworkInterfaceType.Wireless80211;
    15.                 NetworkInterfaceType _type2 = NetworkInterfaceType.Ethernet;
    16.  
    17.                 if ((item.NetworkInterfaceType == _type1 || item.NetworkInterfaceType == _type2) && item.OperationalStatus == OperationalStatus.Up)
    18. #endif
    19.                 {
    20.                     foreach (UnicastIPAddressInformation ip in item.GetIPProperties().UnicastAddresses)
    21.                     {
    22.                         //IPv4
    23.                         if (Addfam == ADDRESSFAM.IPv4)
    24.                         {
    25.                             if (ip.Address.AddressFamily == AddressFamily.InterNetwork)
    26.                             {
    27.                                 if (ip.Address.ToString() != "127.0.0.1")
    28.                                     output = ip.Address.ToString();
    29.                             }
    30.                         }
    31.  
    32.                         //IPv6
    33.                         else if (Addfam == ADDRESSFAM.IPv6)
    34.                         {
    35.                             if (ip.Address.AddressFamily == AddressFamily.InterNetworkV6)
    36.                             {
    37.                                 if (ip.Address.ToString() != "127.0.0.1")
    38.                                     output = ip.Address.ToString();
    39.                             }
    40.                         }
    41.                     }
    42.                 }
    43.             }
    44.             return output;
    45.         }
    with the IPv6, and I guess that's the only reason why I could use the phone's data to share it with other players and let them connect with you locally. Although I remember I discarded this method because it wasn't reliable at all times.

    Do you know of a piece of code that gets the IPv6 in case the IPv4 is null?
     
    Last edited: Jan 20, 2023
  4. GuirieSanchez

    GuirieSanchez

    Joined:
    Oct 12, 2021
    Posts:
    452
    I managed to solve the issue where I will get inconsistent and weird results for the Local IP when phones are connected to the WiFi or WiFi + phone's data.

    What I did is the following:

    Code (CSharp):
    1. public static string[] GetLocalIPv4(NetworkInterfaceType interfaceType = NetworkInterfaceType.Ethernet)
    2.         {
    3.             var ipAddrList = new List<string>();
    4.             //IPv4
    5.             foreach (var netInterface in NetworkInterface.GetAllNetworkInterfaces())
    6.             {
    7.                 if (netInterface.NetworkInterfaceType == interfaceType && netInterface.OperationalStatus == OperationalStatus.Up)
    8.                 {
    9.                     foreach (var ip in netInterface.GetIPProperties().UnicastAddresses)
    10.                     {
    11.                         if (ip.Address.AddressFamily == AddressFamily.InterNetwork)
    12.                         {
    13.                             ipAddrList.Add(ip.Address.ToString());
    14.                         }
    15.                     }
    16.                 }
    17.  
    18.             }
    19.             if (ipAddrList.Count <= 0)
    20.             {
    21.                 Debug.Log("NO IPv4 ADDRESS DETECTED, now I should try getting the phone's data's IP address");
    22.             }
    23.             return ipAddrList.ToArray();
    24.         }
    It seems pretty consistent. It prioritizes the WiFi connection over the phone's data, and if there's no WiFi connection, it should try IPv6 or whatever Local IP is for the phone's data connection.


    Here's the problem. I've tried getting the IPv6 (when disconnecting the phone from the WiFi and using just its data) but I'm not getting what I'm expecting:
    The code is the following:

    Code (CSharp):
    1. public static string[] GetLocalIPv4(NetworkInterfaceType interfaceType = NetworkInterfaceType.Ethernet)
    2.         {
    3.             var ipAddrList = new List<string>();
    4.             //IPv4
    5.             foreach (var netInterface in NetworkInterface.GetAllNetworkInterfaces())
    6.             {
    7.                 if (netInterface.NetworkInterfaceType == interfaceType && netInterface.OperationalStatus == OperationalStatus.Up)
    8.                 {
    9.                     foreach (var ip in netInterface.GetIPProperties().UnicastAddresses)
    10.                     {
    11.                         if (ip.Address.AddressFamily == AddressFamily.InterNetwork)
    12.                         {
    13.                             ipAddrList.Add(ip.Address.ToString());
    14.                         }
    15.                     }
    16.                 }
    17.  
    18.             }
    19.             if (ipAddrList.Count <= 0)
    20.             {
    21.                 Debug.Log("NO IPv4 ADDRESS DETECTED, now trying IPv6");
    22.                 foreach (var netInterface in NetworkInterface.GetAllNetworkInterfaces())
    23.                 {
    24.                     if (netInterface.NetworkInterfaceType == interfaceType && netInterface.OperationalStatus == OperationalStatus.Up)
    25.                     {
    26.                         foreach (var ip in netInterface.GetIPProperties().UnicastAddresses)
    27.                         {
    28.                             if (ip.Address.AddressFamily == AddressFamily.InterNetworkV6) // here's the change
    29.                             {
    30.                                 ipAddrList.Add(ip.Address.ToString());
    31.                             }
    32.                         }
    33.                     }
    34.  
    35.                 }
    36.          
    37.             }
    38.             return ipAddrList.ToArray();
    39.         }
    Again, when using WiFi or WiFi + data, it works perfectly (it reports the WiFi local IP successfully). But with the phone's data (therefore using
    if (ip.Address.AddressFamily == AddressFamily.InterNetworkV6)
    ), it's reporting 3 strings of the following format:

    "fi97::bp7d:3utt:iwrj:e9w7%89"

    which cannot be used for connecting clients.
     
    Last edited: Jan 20, 2023
    RikuTheFuffs likes this.