Added code to call Xamarin.Android internal implementation of getifaddrs/freeifaddrs to provide us
with the required information to fulfill the request.
Added a handful of Linux ARP hardware IDs which are considered to be tunnel devices and which may occur
on Android devices.
Part of fix for https://bugzilla.xamarin.com/show_bug.cgi?id=1969
public ushort sll_hatype;
public byte sll_pkttype;
public byte sll_halen;
-
+#if MONODROID
+ // In MonoDroid the structure has larger space allocated for the address part since there exist
+ // addresses (Infiniband, ipv6 tunnels) which exceed the standard 8 bytes. In fact, glibc's
+ // getifaddrs implementation also uses the bigger size, but for compatibility with other libc
+ // implementations we use the standard address size
+ [MarshalAs (UnmanagedType.ByValArray, SizeConst=24)]
+#else
[MarshalAs (UnmanagedType.ByValArray, SizeConst=8)]
+#endif
public byte[] sll_addr;
}
PRONET = 4,
ATM = 19,
SLIP = 256,
+ CSLIP = 257,
+ SLIP6 = 258,
+ CSLIP6 = 259,
PPP = 512,
LOOPBACK = 772,
FDDI = 774,
TUNNEL = 768,
- TUNNEL6 = 769
+ TUNNEL6 = 769,
+ SIT = 776, // IPv6-in-IPv4 tunnel
+ IPDDP = 777, // IP over DDP tunnel
+ IPGRE = 778, // GRE over IP
+ IP6GRE = 823 // GRE over IPv6
}
}
get { return iface_path; }
}
+ static int GetInterfaceAddresses (out IntPtr ifap)
+ {
+#if MONODROID
+ return AndroidPlatform.GetInterfaceAddresses (out ifap);
+#else
+ return getifaddrs (out ifap);
+#endif
+ }
+
+ static void FreeInterfaceAddresses (IntPtr ifap)
+ {
+#if MONODROID
+ AndroidPlatform.FreeInterfaceAddresses (ifap);
+#else
+ freeifaddrs (ifap);
+#endif
+ }
+
public static NetworkInterface [] ImplGetAllNetworkInterfaces ()
{
var interfaces = new Dictionary <string, LinuxNetworkInterface> ();
IntPtr ifap;
- if (getifaddrs (out ifap) != 0)
+ if (GetInterfaceAddresses (out ifap) != 0)
throw new SystemException ("getifaddrs() failed");
try {
break;
case LinuxArpHardware.SLIP:
+ case LinuxArpHardware.CSLIP:
+ case LinuxArpHardware.SLIP6:
+ case LinuxArpHardware.CSLIP6:
type = NetworkInterfaceType.Slip;
break;
type = NetworkInterfaceType.Fddi;
break;
+ case LinuxArpHardware.SIT:
+ case LinuxArpHardware.IPDDP:
+ case LinuxArpHardware.IPGRE:
+ case LinuxArpHardware.IP6GRE:
case LinuxArpHardware.TUNNEL6:
- goto case LinuxArpHardware.TUNNEL;
-
case LinuxArpHardware.TUNNEL:
type = NetworkInterfaceType.Tunnel;
break;
next = addr.ifa_next;
}
} finally {
- freeifaddrs (ifap);
+ FreeInterfaceAddresses (ifap);
}
NetworkInterface [] result = new NetworkInterface [interfaces.Count];
namespace System {
internal static class AndroidPlatform {
-
+ delegate int GetInterfaceAddressesDelegate (out IntPtr ifap);
+ delegate void FreeInterfaceAddressesDelegate (IntPtr ifap);
+
#if SECURITY_DEP
static readonly Converter<List <byte[]>, bool> trustEvaluateSsl;
#endif // SECURITY_DEP
static readonly Func<IWebProxy> getDefaultProxy;
-
+ static readonly GetInterfaceAddressesDelegate getInterfaceAddresses;
+ static readonly FreeInterfaceAddressesDelegate freeInterfaceAddresses;
static AndroidPlatform ()
{
typeof (Func<IWebProxy>), t, "GetDefaultProxy",
ignoreCase:false,
throwOnBindFailure:true);
+
+ getInterfaceAddresses = (GetInterfaceAddressesDelegate)Delegate.CreateDelegate (
+ typeof (GetInterfaceAddressesDelegate), t, "GetInterfaceAddresses",
+ ignoreCase: false,
+ throwOnBindFailure: false);
+
+ freeInterfaceAddresses = (FreeInterfaceAddressesDelegate)Delegate.CreateDelegate (
+ typeof (FreeInterfaceAddressesDelegate), t, "FreeInterfaceAddresses",
+ ignoreCase: false,
+ throwOnBindFailure: false);
}
#if SECURITY_DEP
{
return getDefaultProxy ();
}
+
+ internal static int GetInterfaceAddresses (out IntPtr ifap)
+ {
+ ifap = IntPtr.Zero;
+ if (getInterfaceAddresses == null)
+ return -1;
+
+ return getInterfaceAddresses (out ifap);
+ }
+
+ internal static void FreeInterfaceAddresses (IntPtr ifap)
+ {
+ if (freeInterfaceAddresses == null)
+ return;
+
+ freeInterfaceAddresses (ifap);
+ }
}
}
#endif // MONODROID