2 // System.Net.NetworkInformation.NetworkInterface
5 // Gonzalo Paniagua Javier (gonzalo@novell.com)
6 // Atsushi Enomoto (atsushi@ximian.com)
7 // Miguel de Icaza (miguel@novell.com)
8 // Eric Butler (eric@extremeboredom.net)
9 // Marek Habersack (mhabersack@novell.com)
10 // Marek Safar (marek.safar@gmail.com)
12 // Copyright (c) 2006-2008 Novell, Inc. (http://www.novell.com)
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 using System.Collections.Generic;
35 using System.Collections;
37 using System.Net.Sockets;
38 using System.Runtime.InteropServices;
41 using System.Globalization;
43 namespace System.Net.NetworkInformation {
44 static class SystemNetworkInterface {
46 static readonly NetworkInterfaceFactory nif = NetworkInterfaceFactory.Create ();
48 public static NetworkInterface [] GetNetworkInterfaces ()
51 return nif.GetAllNetworkInterfaces ();
53 return new NetworkInterface [0];
57 public static bool InternalGetIsNetworkAvailable ()
63 public static int InternalLoopbackInterfaceIndex {
65 return nif.GetLoopbackInterfaceIndex ();
69 public static int InternalIPv6LoopbackInterfaceIndex {
71 throw new NotImplementedException ();
75 public static IPAddress GetNetMask (IPAddress address)
77 return nif.GetNetMask (address);
81 abstract class NetworkInterfaceFactory
83 internal abstract class UnixNetworkInterfaceAPI : NetworkInterfaceFactory
86 public static int if_nametoindex(string ifname)
88 throw new PlatformNotSupportedException ();
91 protected static int getifaddrs (out IntPtr ifap)
93 throw new PlatformNotSupportedException ();
96 protected static void freeifaddrs (IntPtr ifap)
98 throw new PlatformNotSupportedException ();
102 public static extern int if_nametoindex(string ifname);
105 protected static extern int getifaddrs (out IntPtr ifap);
108 protected static extern void freeifaddrs (IntPtr ifap);
112 class MacOsNetworkInterfaceAPI : UnixNetworkInterfaceAPI
114 const int AF_INET = 2;
115 const int AF_INET6 = 30;
116 const int AF_LINK = 18;
118 public override NetworkInterface [] GetAllNetworkInterfaces ()
120 var interfaces = new Dictionary <string, MacOsNetworkInterface> ();
122 if (getifaddrs (out ifap) != 0)
123 throw new SystemException ("getifaddrs() failed");
127 while (next != IntPtr.Zero) {
128 MacOsStructs.ifaddrs addr = (MacOsStructs.ifaddrs) Marshal.PtrToStructure (next, typeof (MacOsStructs.ifaddrs));
129 IPAddress address = IPAddress.None;
130 string name = addr.ifa_name;
132 byte[] macAddress = null;
133 NetworkInterfaceType type = NetworkInterfaceType.Unknown;
135 if (addr.ifa_addr != IntPtr.Zero) {
137 MacOsStructs.sockaddr sockaddr = (MacOsStructs.sockaddr) Marshal.PtrToStructure (addr.ifa_addr, typeof (MacOsStructs.sockaddr));
139 if (sockaddr.sa_family == AF_INET6) {
140 MacOsStructs.sockaddr_in6 sockaddr6 = (MacOsStructs.sockaddr_in6) Marshal.PtrToStructure (addr.ifa_addr, typeof (MacOsStructs.sockaddr_in6));
141 address = new IPAddress (sockaddr6.sin6_addr.u6_addr8, sockaddr6.sin6_scope_id);
142 } else if (sockaddr.sa_family == AF_INET) {
143 MacOsStructs.sockaddr_in sockaddrin = (MacOsStructs.sockaddr_in) Marshal.PtrToStructure (addr.ifa_addr, typeof (MacOsStructs.sockaddr_in));
144 address = new IPAddress (sockaddrin.sin_addr);
145 } else if (sockaddr.sa_family == AF_LINK) {
146 MacOsStructs.sockaddr_dl sockaddrdl = new MacOsStructs.sockaddr_dl ();
147 sockaddrdl.Read (addr.ifa_addr);
149 macAddress = new byte [(int) sockaddrdl.sdl_alen];
150 // copy mac address from sdl_data field starting at last index pos of interface name into array macaddress, starting
152 Array.Copy (sockaddrdl.sdl_data, sockaddrdl.sdl_nlen, macAddress, 0, Math.Min (macAddress.Length, sockaddrdl.sdl_data.Length - sockaddrdl.sdl_nlen));
154 index = sockaddrdl.sdl_index;
156 int hwtype = (int) sockaddrdl.sdl_type;
157 if (Enum.IsDefined (typeof (MacOsArpHardware), hwtype)) {
158 switch ((MacOsArpHardware) hwtype) {
159 case MacOsArpHardware.ETHER:
160 type = NetworkInterfaceType.Ethernet;
163 case MacOsArpHardware.ATM:
164 type = NetworkInterfaceType.Atm;
167 case MacOsArpHardware.SLIP:
168 type = NetworkInterfaceType.Slip;
171 case MacOsArpHardware.PPP:
172 type = NetworkInterfaceType.Ppp;
175 case MacOsArpHardware.LOOPBACK:
176 type = NetworkInterfaceType.Loopback;
180 case MacOsArpHardware.FDDI:
181 type = NetworkInterfaceType.Fddi;
188 MacOsNetworkInterface iface = null;
190 // create interface if not already present
191 if (!interfaces.TryGetValue (name, out iface)) {
192 iface = new MacOsNetworkInterface (name, addr.ifa_flags);
193 interfaces.Add (name, iface);
196 // if a new address has been found, add it
197 if (!address.Equals (IPAddress.None))
198 iface.AddAddress (address);
200 // set link layer info, if iface has macaddress or is loopback device
201 if (macAddress != null || type == NetworkInterfaceType.Loopback)
202 iface.SetLinkLayerInfo (index, macAddress, type);
204 next = addr.ifa_next;
210 NetworkInterface [] result = new NetworkInterface [interfaces.Count];
212 foreach (NetworkInterface thisInterface in interfaces.Values) {
213 result [x] = thisInterface;
219 public override int GetLoopbackInterfaceIndex ()
221 return if_nametoindex ("lo0");
224 public override IPAddress GetNetMask (IPAddress address)
227 if (getifaddrs (out ifap) != 0)
228 throw new SystemException ("getifaddrs() failed");
232 while (next != IntPtr.Zero) {
233 MacOsStructs.ifaddrs addr = (MacOsStructs.ifaddrs) Marshal.PtrToStructure (next, typeof (MacOsStructs.ifaddrs));
235 if (addr.ifa_addr != IntPtr.Zero) {
237 MacOsStructs.sockaddr sockaddr = (MacOsStructs.sockaddr) Marshal.PtrToStructure (addr.ifa_addr, typeof (MacOsStructs.sockaddr));
239 if (sockaddr.sa_family == AF_INET) {
240 MacOsStructs.sockaddr_in sockaddrin = (MacOsStructs.sockaddr_in) Marshal.PtrToStructure (addr.ifa_addr, typeof (MacOsStructs.sockaddr_in));
241 var saddress = new IPAddress (sockaddrin.sin_addr);
242 if (address.Equals (saddress))
243 return new IPAddress(((sockaddr_in)Marshal.PtrToStructure(addr.ifa_netmask, typeof(sockaddr_in))).sin_addr);
246 next = addr.ifa_next;
256 class LinuxNetworkInterfaceAPI : UnixNetworkInterfaceAPI
258 const int AF_INET = 2;
259 const int AF_INET6 = 10;
260 const int AF_PACKET = 17;
262 static void FreeInterfaceAddresses (IntPtr ifap)
265 AndroidPlatform.FreeInterfaceAddresses (ifap);
271 static int GetInterfaceAddresses (out IntPtr ifap)
274 return AndroidPlatform.GetInterfaceAddresses (out ifap);
276 return getifaddrs (out ifap);
280 public override NetworkInterface [] GetAllNetworkInterfaces ()
283 var interfaces = new Dictionary <string, LinuxNetworkInterface> ();
285 if (GetInterfaceAddresses (out ifap) != 0)
286 throw new SystemException ("getifaddrs() failed");
290 while (next != IntPtr.Zero) {
291 ifaddrs addr = (ifaddrs) Marshal.PtrToStructure (next, typeof (ifaddrs));
292 IPAddress address = IPAddress.None;
293 string name = addr.ifa_name;
295 byte[] macAddress = null;
296 NetworkInterfaceType type = NetworkInterfaceType.Unknown;
297 int nullNameCount = 0;
299 if (addr.ifa_addr != IntPtr.Zero) {
300 sockaddr_in sockaddr = (sockaddr_in) Marshal.PtrToStructure (addr.ifa_addr, typeof (sockaddr_in));
302 if (sockaddr.sin_family == AF_INET6) {
303 sockaddr_in6 sockaddr6 = (sockaddr_in6) Marshal.PtrToStructure (addr.ifa_addr, typeof (sockaddr_in6));
304 address = new IPAddress (sockaddr6.sin6_addr.u6_addr8, sockaddr6.sin6_scope_id);
305 } else if (sockaddr.sin_family == AF_INET) {
306 address = new IPAddress (sockaddr.sin_addr);
307 } else if (sockaddr.sin_family == AF_PACKET) {
308 sockaddr_ll sockaddrll = (sockaddr_ll) Marshal.PtrToStructure (addr.ifa_addr, typeof (sockaddr_ll));
309 if (((int)sockaddrll.sll_halen) > sockaddrll.sll_addr.Length){
310 next = addr.ifa_next;
314 macAddress = new byte [(int) sockaddrll.sll_halen];
315 Array.Copy (sockaddrll.sll_addr, 0, macAddress, 0, macAddress.Length);
316 index = sockaddrll.sll_ifindex;
318 int hwtype = (int)sockaddrll.sll_hatype;
319 if (Enum.IsDefined (typeof (LinuxArpHardware), hwtype)) {
320 switch ((LinuxArpHardware)hwtype) {
321 case LinuxArpHardware.EETHER:
322 goto case LinuxArpHardware.ETHER;
324 case LinuxArpHardware.ETHER:
325 type = NetworkInterfaceType.Ethernet;
328 case LinuxArpHardware.PRONET:
329 type = NetworkInterfaceType.TokenRing;
332 case LinuxArpHardware.ATM:
333 type = NetworkInterfaceType.Atm;
336 case LinuxArpHardware.SLIP:
337 case LinuxArpHardware.CSLIP:
338 case LinuxArpHardware.SLIP6:
339 case LinuxArpHardware.CSLIP6:
340 type = NetworkInterfaceType.Slip;
343 case LinuxArpHardware.PPP:
344 type = NetworkInterfaceType.Ppp;
347 case LinuxArpHardware.LOOPBACK:
348 type = NetworkInterfaceType.Loopback;
352 case LinuxArpHardware.FDDI:
353 type = NetworkInterfaceType.Fddi;
356 case LinuxArpHardware.SIT:
357 case LinuxArpHardware.IPDDP:
358 case LinuxArpHardware.IPGRE:
359 case LinuxArpHardware.IP6GRE:
360 case LinuxArpHardware.TUNNEL6:
361 case LinuxArpHardware.TUNNEL:
362 type = NetworkInterfaceType.Tunnel;
369 LinuxNetworkInterface iface = null;
371 if (String.IsNullOrEmpty (name))
372 name = "\0" + (++nullNameCount).ToString ();
374 if (!interfaces.TryGetValue (name, out iface)) {
375 iface = new LinuxNetworkInterface (name);
376 interfaces.Add (name, iface);
379 if (!address.Equals (IPAddress.None))
380 iface.AddAddress (address);
382 if (macAddress != null || type == NetworkInterfaceType.Loopback) {
383 if (type == NetworkInterfaceType.Ethernet) {
384 if (Directory.Exists(iface.IfacePath + "wireless")) {
385 type = NetworkInterfaceType.Wireless80211;
388 iface.SetLinkLayerInfo (index, macAddress, type);
391 next = addr.ifa_next;
394 FreeInterfaceAddresses (ifap);
397 NetworkInterface [] result = new NetworkInterface [interfaces.Count];
399 foreach (NetworkInterface thisInterface in interfaces.Values) {
400 result [x] = thisInterface;
406 public override int GetLoopbackInterfaceIndex ()
408 return if_nametoindex ("lo");
411 public override IPAddress GetNetMask (IPAddress address)
413 foreach (ifaddrs networkInteface in GetNetworkInterfaces()) {
414 if (networkInteface.ifa_addr == IntPtr.Zero)
417 var sockaddr = (sockaddr_in)Marshal.PtrToStructure(networkInteface.ifa_addr, typeof(sockaddr_in));
419 if (sockaddr.sin_family != AF_INET)
422 if (!address.Equals(new IPAddress(sockaddr.sin_addr)))
425 var netmask = (sockaddr_in)Marshal.PtrToStructure(networkInteface.ifa_netmask, typeof(sockaddr_in));
426 return new IPAddress(netmask.sin_addr);
432 private static IEnumerable<ifaddrs> GetNetworkInterfaces()
434 IntPtr ifap = IntPtr.Zero;
437 if (GetInterfaceAddresses(out ifap) != 0)
441 while (next != IntPtr.Zero) {
442 var addr = (ifaddrs)Marshal.PtrToStructure(next, typeof(ifaddrs));
444 next = addr.ifa_next;
447 if (ifap != IntPtr.Zero)
448 FreeInterfaceAddresses(ifap);
454 class Win32NetworkInterfaceAPI : NetworkInterfaceFactory
456 private const string IPHLPAPI = "iphlpapi.dll";
458 [DllImport (IPHLPAPI, SetLastError = true)]
459 static extern int GetAdaptersAddresses (uint family, uint flags, IntPtr reserved, IntPtr info, ref int size);
461 [DllImport (IPHLPAPI)]
462 static extern uint GetBestInterfaceEx (byte[] ipAddress, out int index);
464 static Win32_IP_ADAPTER_ADDRESSES [] GetAdaptersAddresses ()
466 IntPtr ptr = IntPtr.Zero;
468 GetAdaptersAddresses (0, 0, IntPtr.Zero, ptr, ref len);
469 ptr = Marshal.AllocHGlobal(len);
470 int ret = GetAdaptersAddresses (0, 0, IntPtr.Zero, ptr, ref len);
472 throw new NetworkInformationException (ret);
474 List<Win32_IP_ADAPTER_ADDRESSES> l = new List<Win32_IP_ADAPTER_ADDRESSES> ();
475 Win32_IP_ADAPTER_ADDRESSES info;
476 for (IntPtr p = ptr; p != IntPtr.Zero; p = info.Next) {
477 info = Marshal.PtrToStructure<Win32_IP_ADAPTER_ADDRESSES> (p);
484 public override NetworkInterface [] GetAllNetworkInterfaces ()
486 // Win32_IP_ADAPTER_INFO [] ai = GetAdaptersInfo ();
487 Win32_IP_ADAPTER_ADDRESSES [] aa = GetAdaptersAddresses ();
488 NetworkInterface [] ret = new NetworkInterface [aa.Length];
489 for (int i = 0; i < ret.Length; i++)
490 ret [i] = new Win32NetworkInterface2 (aa [i]);
494 private static int GetBestInterfaceForAddress (IPAddress addr) {
496 SocketAddress address = new SocketAddress (addr);
497 int error = (int) GetBestInterfaceEx (address.m_Buffer, out index);
499 throw new NetworkInformationException (error);
505 public override int GetLoopbackInterfaceIndex ()
507 return GetBestInterfaceForAddress (IPAddress.Loopback);
510 public override IPAddress GetNetMask (IPAddress address)
512 throw new NotImplementedException ();
517 public abstract NetworkInterface [] GetAllNetworkInterfaces ();
518 public abstract int GetLoopbackInterfaceIndex ();
519 public abstract IPAddress GetNetMask (IPAddress address);
521 public static NetworkInterfaceFactory Create ()
523 #if MONOTOUCH || XAMMAC
524 return new MacOsNetworkInterfaceAPI ();
526 bool runningOnUnix = (Environment.OSVersion.Platform == PlatformID.Unix);
529 if (Platform.IsMacOS || Platform.IsFreeBSD)
530 return new MacOsNetworkInterfaceAPI ();
532 return new LinuxNetworkInterfaceAPI ();
536 Version windowsVer51 = new Version (5, 1);
537 if (Environment.OSVersion.Version >= windowsVer51)
538 return new Win32NetworkInterfaceAPI ();
541 throw new NotImplementedException ();
546 abstract class UnixNetworkInterface : NetworkInterface
549 protected IPv4InterfaceStatistics ipv4stats;
550 protected IPInterfaceProperties ipproperties;
554 protected List <IPAddress> addresses;
556 NetworkInterfaceType type;
558 internal UnixNetworkInterface (string name)
561 addresses = new List<IPAddress> ();
564 internal void AddAddress (IPAddress address)
566 addresses.Add (address);
569 internal void SetLinkLayerInfo (int index, byte[] macAddress, NetworkInterfaceType type)
571 //this.index = index;
572 this.macAddress = macAddress;
576 public override PhysicalAddress GetPhysicalAddress ()
578 if (macAddress != null)
579 return new PhysicalAddress (macAddress);
581 return PhysicalAddress.None;
584 public override bool Supports (NetworkInterfaceComponent networkInterfaceComponent)
586 bool wantIPv4 = networkInterfaceComponent == NetworkInterfaceComponent.IPv4;
587 bool wantIPv6 = wantIPv4 ? false : networkInterfaceComponent == NetworkInterfaceComponent.IPv6;
589 foreach (IPAddress address in addresses) {
590 if (wantIPv4 && address.AddressFamily == AddressFamily.InterNetwork)
592 else if (wantIPv6 && address.AddressFamily == AddressFamily.InterNetworkV6)
599 public override string Description {
603 public override string Id {
607 public override bool IsReceiveOnly {
608 get { return false; }
611 public override string Name {
615 public override NetworkInterfaceType NetworkInterfaceType {
619 [MonoTODO ("Parse dmesg?")]
620 public override long Speed {
627 internal int NameIndex {
629 return NetworkInterfaceFactory.UnixNetworkInterfaceAPI.if_nametoindex (Name);
635 // This class needs support from the libsupport.so library to fetch the
636 // data using arch-specific ioctls.
638 // For this to work, we have to create this on the factory above.
640 sealed class LinuxNetworkInterface : UnixNetworkInterface
642 //NetworkInterfaceType type;
644 string iface_operstate_path;
645 string iface_flags_path;
648 [DllImport ("__Internal")]
649 static extern int _monodroid_get_android_api_level ();
651 [DllImport ("__Internal")]
652 static extern bool _monodroid_get_network_interface_up_state (string ifname, ref bool is_up);
654 [DllImport ("__Internal")]
655 static extern bool _monodroid_get_network_interface_supports_multicast (string ifname, ref bool supports_multicast);
657 bool android_use_java_api;
660 internal string IfacePath {
661 get { return iface_path; }
664 internal LinuxNetworkInterface (string name)
667 iface_path = "/sys/class/net/" + name + "/";
668 iface_operstate_path = iface_path + "operstate";
669 iface_flags_path = iface_path + "flags";
671 android_use_java_api = _monodroid_get_android_api_level () >= 24;
675 public override IPInterfaceProperties GetIPProperties ()
677 if (ipproperties == null)
678 ipproperties = new LinuxIPInterfaceProperties (this, addresses);
682 public override IPv4InterfaceStatistics GetIPv4Statistics ()
684 if (ipv4stats == null)
685 ipv4stats = new LinuxIPv4InterfaceStatistics (this);
689 public override OperationalStatus OperationalStatus {
692 if (android_use_java_api) {
693 // Starting from API 24 (Android 7 "Nougat") Android restricts access to many
694 // files in the /sys filesystem (see https://code.google.com/p/android/issues/detail?id=205565
695 // for more information) and therefore we are forced to call into Java API in
696 // order to get the information. Alas, what we can obtain in this way is quite
697 // limited. In the case of OperationalStatus we can only determine whether the
698 // interface is up or down. There is a way to get more detailed information but
699 // it requires an instance of the Android Context class which is not available
702 if (_monodroid_get_network_interface_up_state (Name, ref is_up))
703 return is_up ? OperationalStatus.Up : OperationalStatus.Down;
705 return OperationalStatus.Unknown;
708 if (!Directory.Exists (iface_path))
709 return OperationalStatus.Unknown;
712 string s = ReadLine (iface_operstate_path);
716 return OperationalStatus.Unknown;
719 return OperationalStatus.NotPresent;
722 return OperationalStatus.Down;
724 case "lowerlayerdown":
725 return OperationalStatus.LowerLayerDown;
728 return OperationalStatus.Testing;
731 return OperationalStatus.Dormant;
734 return OperationalStatus.Up;
738 return OperationalStatus.Unknown;
742 public override bool SupportsMulticast {
745 if (android_use_java_api) {
746 // Starting from API 24 (Android 7 "Nougat") Android restricts access to many
747 // files in the /sys filesystem (see https://code.google.com/p/android/issues/detail?id=205565
748 // for more information) and therefore we are forced to call into Java API in
749 // order to get the information.
750 bool supports_multicast = false;
751 _monodroid_get_network_interface_supports_multicast (Name, ref supports_multicast);
752 return supports_multicast;
755 if (!Directory.Exists (iface_path))
759 string s = ReadLine (iface_flags_path);
760 if (s.Length > 2 && s [0] == '0' && s [1] == 'x')
763 ulong f = UInt64.Parse (s, NumberStyles.HexNumber);
765 // Hardcoded, only useful for Linux.
766 return ((f & 0x1000) == 0x1000);
773 internal static string ReadLine (string path)
775 using (FileStream fs = File.OpenRead (path)){
776 using (StreamReader sr = new StreamReader (fs)){
777 return sr.ReadLine ();
783 sealed class MacOsNetworkInterface : UnixNetworkInterface
785 private uint _ifa_flags;
787 internal MacOsNetworkInterface (string name, uint ifa_flags)
790 _ifa_flags = ifa_flags;
793 public override IPInterfaceProperties GetIPProperties ()
795 if (ipproperties == null)
796 ipproperties = new MacOsIPInterfaceProperties (this, addresses);
800 public override IPv4InterfaceStatistics GetIPv4Statistics ()
802 if (ipv4stats == null)
803 ipv4stats = new MacOsIPv4InterfaceStatistics (this);
807 public override OperationalStatus OperationalStatus {
809 if(((MacOsInterfaceFlags)_ifa_flags & MacOsInterfaceFlags.IFF_UP) == MacOsInterfaceFlags.IFF_UP){
810 return OperationalStatus.Up;
812 return OperationalStatus.Unknown;
816 public override bool SupportsMulticast {
818 return ((MacOsInterfaceFlags)_ifa_flags & MacOsInterfaceFlags.IFF_MULTICAST) == MacOsInterfaceFlags.IFF_MULTICAST;
824 class Win32NetworkInterface2 : NetworkInterface
826 [DllImport ("iphlpapi.dll", SetLastError = true)]
827 static extern int GetAdaptersInfo (IntPtr info, ref int size);
829 [DllImport ("iphlpapi.dll", SetLastError = true)]
830 static extern int GetIfEntry (ref Win32_MIB_IFROW row);
832 public static Win32_IP_ADAPTER_INFO GetAdapterInfoByIndex (int index)
834 foreach (Win32_IP_ADAPTER_INFO info in GetAdaptersInfo ())
835 if (info.Index == index)
837 throw new IndexOutOfRangeException ("No adapter found for index " + index);
840 static Win32_IP_ADAPTER_INFO [] GetAdaptersInfo ()
843 IntPtr ptr = IntPtr.Zero;
844 GetAdaptersInfo (ptr, ref len);
845 ptr = Marshal.AllocHGlobal(len);
846 int ret = GetAdaptersInfo (ptr, ref len);
849 throw new NetworkInformationException (ret);
851 List<Win32_IP_ADAPTER_INFO> l = new List<Win32_IP_ADAPTER_INFO> ();
852 Win32_IP_ADAPTER_INFO info;
853 for (IntPtr p = ptr; p != IntPtr.Zero; p = info.Next) {
854 info = Marshal.PtrToStructure<Win32_IP_ADAPTER_INFO> (p);
860 Win32_IP_ADAPTER_ADDRESSES addr;
861 Win32_MIB_IFROW mib4, mib6;
862 Win32IPv4InterfaceStatistics ip4stats;
863 IPInterfaceProperties ip_if_props;
865 internal Win32NetworkInterface2 (Win32_IP_ADAPTER_ADDRESSES addr)
868 mib4 = default (Win32_MIB_IFROW);
869 mib4.Index = addr.Alignment.IfIndex;
870 if (GetIfEntry (ref mib4) != 0)
871 mib4.Index = -1; // unavailable;
872 mib6 = default (Win32_MIB_IFROW);
873 mib6.Index = addr.Ipv6IfIndex;
874 if (GetIfEntry (ref mib6) != 0)
875 mib6.Index = -1; // unavailable;
876 ip4stats = new Win32IPv4InterfaceStatistics (mib4);
877 ip_if_props = new Win32IPInterfaceProperties2 (addr, mib4, mib6);
880 public override IPInterfaceProperties GetIPProperties ()
885 public override IPv4InterfaceStatistics GetIPv4Statistics ()
890 public override PhysicalAddress GetPhysicalAddress ()
892 byte [] bytes = new byte [addr.PhysicalAddressLength];
893 Array.Copy (addr.PhysicalAddress, 0, bytes, 0, bytes.Length);
894 return new PhysicalAddress (bytes);
897 public override bool Supports (NetworkInterfaceComponent networkInterfaceComponent)
899 switch (networkInterfaceComponent) {
900 case NetworkInterfaceComponent.IPv4:
901 return mib4.Index >= 0;
902 case NetworkInterfaceComponent.IPv6:
903 return mib6.Index >= 0;
908 public override string Description {
909 get { return addr.Description; }
911 public override string Id {
912 get { return addr.AdapterName; }
914 public override bool IsReceiveOnly {
915 get { return addr.IsReceiveOnly; }
917 public override string Name {
918 get { return addr.FriendlyName; }
920 public override NetworkInterfaceType NetworkInterfaceType {
921 get { return addr.IfType; }
923 public override OperationalStatus OperationalStatus {
924 get { return addr.OperStatus; }
926 public override long Speed {
927 get { return mib6.Index >= 0 ? mib6.Speed : mib4.Speed; }
929 public override bool SupportsMulticast {
930 get { return !addr.NoMulticast; }