3 /// Provides support for ip configuation information and statistics.
6 namespace System.Net.NetworkInformation {
8 using System.Net.Sockets;
10 using System.Runtime.InteropServices;
11 using System.Collections.Generic;
12 using System.Diagnostics.Contracts;
14 internal class SystemNetworkInterface:NetworkInterface {
19 private string description;
20 private byte[] physicalAddress;
21 private uint addressLength;
22 private NetworkInterfaceType type;
23 private OperationalStatus operStatus;
25 //Unfortunately, any interface can
26 //have two completely different valid indexes for ipv4 and ipv6
27 private uint index = 0;
28 private uint ipv6Index = 0;
29 private AdapterFlags adapterFlags;
30 private SystemIPInterfaceProperties interfaceProperties = null;
32 internal static int InternalLoopbackInterfaceIndex {
34 return GetBestInterfaceForAddress(IPAddress.Loopback);
38 internal static int InternalIPv6LoopbackInterfaceIndex {
40 return GetBestInterfaceForAddress(IPAddress.IPv6Loopback);
44 private static int GetBestInterfaceForAddress(IPAddress addr) {
46 SocketAddress address = new SocketAddress(addr);
47 int error = (int)UnsafeNetInfoNativeMethods.GetBestInterfaceEx(address.m_Buffer, out index);
49 throw new NetworkInformationException(error);
55 internal static bool InternalGetIsNetworkAvailable(){
58 NetworkInterface[] networkInterfaces = GetNetworkInterfaces();
59 foreach (NetworkInterface netInterface in networkInterfaces) {
60 if (netInterface.OperationalStatus == OperationalStatus.Up && netInterface.NetworkInterfaceType != NetworkInterfaceType.Tunnel
61 && netInterface.NetworkInterfaceType != NetworkInterfaceType.Loopback){
66 catch (NetworkInformationException nie) {
67 if (Logging.On) Logging.Exception(Logging.Web, "SystemNetworkInterface", "InternalGetIsNetworkAvailable", nie);
74 [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods",
75 Justification = "DangerousGetHandle is required for marshaling")]
76 internal static NetworkInterface[] GetNetworkInterfaces() {
77 Contract.Ensures(Contract.Result<NetworkInterface[]>() != null);
78 AddressFamily family = AddressFamily.Unspecified;
80 SafeLocalFree buffer = null;
81 FixedInfo fixedInfo = SystemIPGlobalProperties.GetFixedInfo();
82 List<SystemNetworkInterface> interfaceList = new List<SystemNetworkInterface>();
84 GetAdaptersAddressesFlags flags =
85 GetAdaptersAddressesFlags.IncludeGateways
86 | GetAdaptersAddressesFlags.IncludeWins;
88 // Figure out the right buffer size for the adapter information
89 uint result = UnsafeNetInfoNativeMethods.GetAdaptersAddresses(
90 family, (uint)flags, IntPtr.Zero, SafeLocalFree.Zero, ref bufferSize);
92 while (result == IpHelperErrors.ErrorBufferOverflow) {
94 // Allocate the buffer and get the adapter info
95 buffer = SafeLocalFree.LocalAlloc((int)bufferSize);
96 result = UnsafeNetInfoNativeMethods.GetAdaptersAddresses(
97 family, (uint)flags, IntPtr.Zero, buffer, ref bufferSize);
99 // If succeeded, we're going to add each new interface
100 if (result == IpHelperErrors.Success) {
101 // Linked list of interfaces
102 IntPtr ptr = buffer.DangerousGetHandle();
103 while (ptr != IntPtr.Zero) {
104 // Traverse the list, marshal in the native structures, and create new NetworkInterfaces
105 IpAdapterAddresses adapterAddresses =
106 (IpAdapterAddresses)Marshal.PtrToStructure(ptr, typeof(IpAdapterAddresses));
107 interfaceList.Add(new SystemNetworkInterface(fixedInfo, adapterAddresses));
109 ptr = adapterAddresses.next;
114 if (buffer != null) {
121 // if we don't have any interfaces detected, return empty.
122 if (result == IpHelperErrors.ErrorNoData || result == IpHelperErrors.ErrorInvalidParameter) {
123 return new SystemNetworkInterface[0];
126 // Otherwise we throw on an error
127 if (result != IpHelperErrors.Success) {
128 throw new NetworkInformationException((int)result);
131 return interfaceList.ToArray();
135 internal SystemNetworkInterface(FixedInfo fixedInfo, IpAdapterAddresses ipAdapterAddresses) {
136 //store the common api information
137 id = ipAdapterAddresses.AdapterName;
138 name = ipAdapterAddresses.friendlyName;
139 description = ipAdapterAddresses.description;
140 index = ipAdapterAddresses.index;
142 physicalAddress = ipAdapterAddresses.address;
143 addressLength = ipAdapterAddresses.addressLength;
145 type = ipAdapterAddresses.type;
146 operStatus = ipAdapterAddresses.operStatus;
147 speed = (long)ipAdapterAddresses.receiveLinkSpeed;
150 ipv6Index = ipAdapterAddresses.ipv6Index;
152 adapterFlags = ipAdapterAddresses.flags;
153 interfaceProperties = new SystemIPInterfaceProperties(fixedInfo, ipAdapterAddresses);
158 public override string Id{get {return id;}}
159 public override string Name{get {return name;}}
160 public override string Description{get {return description;}}
162 public override PhysicalAddress GetPhysicalAddress(){
163 byte[] newAddr = new byte[addressLength];
164 Array.Copy(physicalAddress,newAddr,addressLength);
165 return new PhysicalAddress(newAddr);
167 public override NetworkInterfaceType NetworkInterfaceType{get {return type;}}
169 public override IPInterfaceProperties GetIPProperties(){
170 return interfaceProperties;
173 /// Despite the naming, the results are not IPv4 specific.
174 /// Do not use this method, use GetIPStatistics instead.
175 /// <include file='doc\NetworkInterface.uex' path='docs/doc[@for="NetworkInterface.GetInterfaceStatistics"]/*' />
176 public override IPv4InterfaceStatistics GetIPv4Statistics(){
177 return new SystemIPv4InterfaceStatistics(index);
180 public override IPInterfaceStatistics GetIPStatistics() {
181 return new SystemIPInterfaceStatistics(index);
184 public override bool Supports(NetworkInterfaceComponent networkInterfaceComponent){
185 if (networkInterfaceComponent == NetworkInterfaceComponent.IPv6
186 && ((adapterFlags & AdapterFlags.IPv6Enabled) != 0)) {
189 if (networkInterfaceComponent == NetworkInterfaceComponent.IPv4
190 && ((adapterFlags & AdapterFlags.IPv4Enabled) != 0)) {
196 //We cache this to be consistent across all platforms
197 public override OperationalStatus OperationalStatus{
203 public override long Speed{
209 public override bool IsReceiveOnly {
211 return ((adapterFlags & AdapterFlags.ReceiveOnly) > 0);
214 /// <summary>The interface doesn't allow multicast.</summary>
215 public override bool SupportsMulticast {
217 return ((adapterFlags & AdapterFlags.NoMulticast) == 0);